<commit_before>// Copyright 2016 Volker Sorge
//
// 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.
//
// Supported by the Mozilla Foundation.

/**
 * @fileoverview A data structure to maintain grammatical context.
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.Grammar');

goog.require('sre.Engine');

/**
 * @constructor
 */
sre.Grammar = function() {

  /**
   * Grammatical annotations that need to be propagated.
   * @type {!sre.Grammar.State}
   * @private
   */
  this.parameters_ = {};

  /**
   * Maps grammatical annotations to correction functions.
   * @type {Object.<Function>}
   * @private
   */
  this.corrections_ = {};

  /**
   * Maps grammatical annotations to preprocessor functions.
   * @type {Object.<Function>}
   * @private
   */
  this.preprocessors_ = {};

  /**
   * @type {Array.<Object.<sre.Grammar.Value>>}
   * @private
   */
  this.stateStack_ = [];

  /**
   * Current processing flags of the grammar. This is only filled during
   * application of grammatical structures to an input text.
   * @type {{adjust: (undefined|boolean),
   *         preprocess: (undefined|boolean),
   *         correct: (undefined|boolean),
   *         translate: (undefined|boolean)}}
   */
  this.currentFlags = {};

};
goog.addSingletonGetter(sre.Grammar);

/**
 * @typedef {boolean|string}
 */
sre.Grammar.Value;

/**
 * Defines grammar attribute for a component of a speech rule.
 * @typedef {!Object.<sre.Grammar.Value>}
 */
sre.Grammar.State;

/**
 * @type {string}
 */
sre.Grammar.ATTRIBUTE = 'grammar';

/**
 * Clears the grammar object.
 */
sre.Grammar.prototype.clear = function() {
  this.parameters_ = {};
  this.stateStack_ = [];
};

/**
 * Sets a grammar parameter.
 * @param {string} parameter The parameter name.
 * @param {sre.Grammar.Value} value The parameter's value.
 * @return {sre.Grammar.Value} The old value if it existed.
 */
sre.Grammar.prototype.setParameter = function(parameter, value) {
  var oldValue = this.parameters_[parameter];
  value ? this.parameters_[parameter] = value :
      delete this.parameters_[parameter];
  return oldValue;
};

/**
 * Returns the value for a parameter.
 * @param {string} parameter The parameter name.
 * @return {sre.Grammar.Value} Value of a parameter if it exists.
 */
sre.Grammar.prototype.getParameter = function(parameter) {
  return this.parameters_[parameter];
};

/**
 * Sets a grammar correction.
 * @param {string} correction The correction name.
 * @param {Function} func The correction function.
 */
sre.Grammar.prototype.setCorrection = function(correction, func) {
  this.corrections_[correction] = func;
};

/**
 * Sets a grammar preprocessor.
 * @param {string} preprocessor The preprocessor name.
 * @param {Function} func The preprocessor function.
 */
sre.Grammar.prototype.setPreprocessor = function(preprocessor, func) {
  this.preprocessors_[preprocessor] = func;
};

/**
 * Returns a grammar correction function if it exists.
 * @param {string} correction The grammar annotation.
 * @return {Function} The correction function.
 */
sre.Grammar.prototype.getCorrection = function(correction) {
  return this.corrections_[correction];
};

/**
 * @return {string} A string version of the grammatical state.
 */
sre.Grammar.prototype.getState = function() {
  var pairs = [];
  for (var key in this.parameters_) {
    var value = this.parameters_[key];
    pairs.push(typeof value === 'string' ? key + ':' + value : key);
  }
  return pairs.join(' ');
};

/**
 * Saves the current state of the grammar object.
 * @param {Object.<sre.Grammar.Value>} assignment A list of key value
 *     pairs.
 */
sre.Grammar.prototype.pushState = function(assignment) {
  for (var key in assignment) {
    assignment[key] = this.setParameter(key, assignment[key]);
  }
  this.stateStack_.push(assignment);
};

/**
 * Saves the current state of the grammar object.
 */
sre.Grammar.prototype.popState = function() {
  var assignment = this.stateStack_.pop();
  for (var key in assignment) {
    this.setParameter(key, assignment[key]);
  }
};

/**
 * Adds the grammatical state as attributed to an XML node.
 * @param {Node} node Adds a grammar value to the node.
 */
sre.Grammar.prototype.setAttribute = function(node) {
  if (node && node.nodeType === sre.DomUtil.NodeType.ELEMENT_NODE) {
    var state = this.getState();
    if (state) {
      node.setAttribute(sre.Grammar.ATTRIBUTE, state);
    }
  }
};

/**
 * Applies a grammatical preprocessors to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.preprocess = function(text) {
  return this.runProcessors_(text, this.preprocessors_);
};

/**
 * Applies a grammatical corrections to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.correct = function(text) {
  return this.runProcessors_(text, this.corrections_);
};

/**
 * Applies a grammatical processors to a given description text.
 * @param {string} text The original description text.
 * @param {Object.<Function>} funcs Dictionary of processor functions.
 * @return {string} The grammatically corrected string.
 * @private
 */
sre.Grammar.prototype.runProcessors_ = function(text, funcs) {
  for (var key in this.parameters_) {
    var func = funcs[key];
    if (!func) {
      continue;
    }
    var value = this.parameters_[key];
    text = (value === true) ? func(text) : func(text, value);
  }
  return text;
};

/**
 * Process a math expression into a string suitable for a speech engine.
 * @param {string} text Text representing a math expression.
 * @return {string} The string with a spoken version of the math expression.
 * @private
 */
sre.Grammar.translateString_ = function(text) {
  var engine = sre.Engine.getInstance();
  return engine.evaluator(text, engine.dynamicCstr) || text;
};

/**
 * Apply grammatical adjustments of the current state to a text string.
 * @param {string} text The text string to be processed.
 * @param {{adjust: (undefined|boolean),
 *          preprocess: (undefined|boolean),
 *          correct: (undefined|boolean),
 *          translate: (undefined|boolean)}=} opt_flags Flags indicating
 *     what adjustments should be carried out.
 *
 * Description of flags:
 * adjust: All grammar adjustments are performed.
 * preprocess: Only grammar preprocessing is performed.
 * correct: Only grammar corrections are performed.
 * translate: Text element is translated with math mappings.
 *
 * @return {string} The transformed text.
 */
sre.Grammar.prototype.apply = function(text, opt_flags) {
  this.currentFlags = opt_flags || {};
  text = (this.currentFlags.adjust || this.currentFlags.preprocess) ?
      sre.Grammar.getInstance().preprocess(text) :
      text;
  if (this.parameters_['translate'] || this.currentFlags.translate) {
    text = sre.Grammar.translateString_(text);
  }
  text = (this.currentFlags.adjust || this.currentFlags.correct) ?
      sre.Grammar.getInstance().correct(text) :
      text;
  this.currentFlags = {};
  return text;
};

/**
 * Parses a state string that can be passed to the grammar.
 * @param {string} stateStr The state string for the grammar.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseState = function(stateStr) {
  var state = {};
  var corrections = stateStr.split(' ');
  for (var i = 0, l = corrections.length; i < l; i++) {
    var corr = corrections[i].split(':');
    var key = corr[0];
    var value = corr[1];
    state[key] = value ? value : true;
  }
  return state;
};

/**
 * Processes the grammar annotations of a rule.
 * @param {string} grammar The grammar annotations.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseInput = function(grammar) {
  var attributes = {};
  var components = grammar.split(':');
  for (var i = 0, l = components.length; i < l; i++) {
    var comp = components[i].split('=');
    var key = comp[0].trim();
    if (comp[1]) {
      attributes[key] = comp[1].trim();
      continue;
    }
    key.match(/^!/) ? attributes[key.slice(1)] = false : attributes[key] = true;
  }
  return attributes;
};

// TODO: The following is temporary and needs a better place.
//
/**
 * Applies a corrective string to the given description text.
 * @param {string} text The original description text.
 * @param {string} correction The correction string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.correctFont_ = function(text, correction) {
  if (!correction || !text) {
    return text;
  }
  // TODO: Combine with localFont.
  correction = sre.Messages.MS_FUNC.FONT_REGEXP(sre.L10n.getLocale().FONT[correction] || correction);
  // var correctionComp = correction.split(/ |-/);
  // var regExp = new RegExp('^' + correctionComp.join('( |-)') + '( |-)');
  return text.replace(correction, '');
};

/**
 * Attaches an annotation to a description.
 * @param {string} text The original description text.
 * @param {string} annotation The annotation string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.addAnnotation_ = function(text, annotation) {
  return text + ':' + annotation;
};

sre.Grammar.noTranslateText_ = function(text) {
  if (text.match(new RegExp('^[' + sre.Messages.REGEXP.TEXT + ']+$'))) {
    sre.Grammar.getInstance().currentFlags['translate'] = false;
  }
  return text;
};

sre.Grammar.getInstance().setCorrection('ignoreFont',
                                        sre.Grammar.correctFont_);
sre.Grammar.getInstance().setPreprocessor('annotation',
                                          sre.Grammar.addAnnotation_);
sre.Grammar.getInstance().setPreprocessor('noTranslateText',
                                          sre.Grammar.noTranslateText_);
sre.Grammar.getInstance().setCorrection('ignoreCaps',
                                        sre.Grammar.correctFont_);

<commit_msg>Cleanup of font correction.<commit_after>// Copyright 2016 Volker Sorge
//
// 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.
//
// Supported by the Mozilla Foundation.

/**
 * @fileoverview A data structure to maintain grammatical context.
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.Grammar');

goog.require('sre.Engine');

/**
 * @constructor
 */
sre.Grammar = function() {

  /**
   * Grammatical annotations that need to be propagated.
   * @type {!sre.Grammar.State}
   * @private
   */
  this.parameters_ = {};

  /**
   * Maps grammatical annotations to correction functions.
   * @type {Object.<Function>}
   * @private
   */
  this.corrections_ = {};

  /**
   * Maps grammatical annotations to preprocessor functions.
   * @type {Object.<Function>}
   * @private
   */
  this.preprocessors_ = {};

  /**
   * @type {Array.<Object.<sre.Grammar.Value>>}
   * @private
   */
  this.stateStack_ = [];

  /**
   * Current processing flags of the grammar. This is only filled during
   * application of grammatical structures to an input text.
   * @type {{adjust: (undefined|boolean),
   *         preprocess: (undefined|boolean),
   *         correct: (undefined|boolean),
   *         translate: (undefined|boolean)}}
   */
  this.currentFlags = {};

};
goog.addSingletonGetter(sre.Grammar);

/**
 * @typedef {boolean|string}
 */
sre.Grammar.Value;

/**
 * Defines grammar attribute for a component of a speech rule.
 * @typedef {!Object.<sre.Grammar.Value>}
 */
sre.Grammar.State;

/**
 * @type {string}
 */
sre.Grammar.ATTRIBUTE = 'grammar';

/**
 * Clears the grammar object.
 */
sre.Grammar.prototype.clear = function() {
  this.parameters_ = {};
  this.stateStack_ = [];
};

/**
 * Sets a grammar parameter.
 * @param {string} parameter The parameter name.
 * @param {sre.Grammar.Value} value The parameter's value.
 * @return {sre.Grammar.Value} The old value if it existed.
 */
sre.Grammar.prototype.setParameter = function(parameter, value) {
  var oldValue = this.parameters_[parameter];
  value ? this.parameters_[parameter] = value :
      delete this.parameters_[parameter];
  return oldValue;
};

/**
 * Returns the value for a parameter.
 * @param {string} parameter The parameter name.
 * @return {sre.Grammar.Value} Value of a parameter if it exists.
 */
sre.Grammar.prototype.getParameter = function(parameter) {
  return this.parameters_[parameter];
};

/**
 * Sets a grammar correction.
 * @param {string} correction The correction name.
 * @param {Function} func The correction function.
 */
sre.Grammar.prototype.setCorrection = function(correction, func) {
  this.corrections_[correction] = func;
};

/**
 * Sets a grammar preprocessor.
 * @param {string} preprocessor The preprocessor name.
 * @param {Function} func The preprocessor function.
 */
sre.Grammar.prototype.setPreprocessor = function(preprocessor, func) {
  this.preprocessors_[preprocessor] = func;
};

/**
 * Returns a grammar correction function if it exists.
 * @param {string} correction The grammar annotation.
 * @return {Function} The correction function.
 */
sre.Grammar.prototype.getCorrection = function(correction) {
  return this.corrections_[correction];
};

/**
 * @return {string} A string version of the grammatical state.
 */
sre.Grammar.prototype.getState = function() {
  var pairs = [];
  for (var key in this.parameters_) {
    var value = this.parameters_[key];
    pairs.push(typeof value === 'string' ? key + ':' + value : key);
  }
  return pairs.join(' ');
};

/**
 * Saves the current state of the grammar object.
 * @param {Object.<sre.Grammar.Value>} assignment A list of key value
 *     pairs.
 */
sre.Grammar.prototype.pushState = function(assignment) {
  for (var key in assignment) {
    assignment[key] = this.setParameter(key, assignment[key]);
  }
  this.stateStack_.push(assignment);
};

/**
 * Saves the current state of the grammar object.
 */
sre.Grammar.prototype.popState = function() {
  var assignment = this.stateStack_.pop();
  for (var key in assignment) {
    this.setParameter(key, assignment[key]);
  }
};

/**
 * Adds the grammatical state as attributed to an XML node.
 * @param {Node} node Adds a grammar value to the node.
 */
sre.Grammar.prototype.setAttribute = function(node) {
  if (node && node.nodeType === sre.DomUtil.NodeType.ELEMENT_NODE) {
    var state = this.getState();
    if (state) {
      node.setAttribute(sre.Grammar.ATTRIBUTE, state);
    }
  }
};

/**
 * Applies a grammatical preprocessors to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.preprocess = function(text) {
  return this.runProcessors_(text, this.preprocessors_);
};

/**
 * Applies a grammatical corrections to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.correct = function(text) {
  return this.runProcessors_(text, this.corrections_);
};

/**
 * Applies a grammatical processors to a given description text.
 * @param {string} text The original description text.
 * @param {Object.<Function>} funcs Dictionary of processor functions.
 * @return {string} The grammatically corrected string.
 * @private
 */
sre.Grammar.prototype.runProcessors_ = function(text, funcs) {
  for (var key in this.parameters_) {
    var func = funcs[key];
    if (!func) {
      continue;
    }
    var value = this.parameters_[key];
    text = (value === true) ? func(text) : func(text, value);
  }
  return text;
};

/**
 * Process a math expression into a string suitable for a speech engine.
 * @param {string} text Text representing a math expression.
 * @return {string} The string with a spoken version of the math expression.
 * @private
 */
sre.Grammar.translateString_ = function(text) {
  var engine = sre.Engine.getInstance();
  return engine.evaluator(text, engine.dynamicCstr) || text;
};

/**
 * Apply grammatical adjustments of the current state to a text string.
 * @param {string} text The text string to be processed.
 * @param {{adjust: (undefined|boolean),
 *          preprocess: (undefined|boolean),
 *          correct: (undefined|boolean),
 *          translate: (undefined|boolean)}=} opt_flags Flags indicating
 *     what adjustments should be carried out.
 *
 * Description of flags:
 * adjust: All grammar adjustments are performed.
 * preprocess: Only grammar preprocessing is performed.
 * correct: Only grammar corrections are performed.
 * translate: Text element is translated with math mappings.
 *
 * @return {string} The transformed text.
 */
sre.Grammar.prototype.apply = function(text, opt_flags) {
  this.currentFlags = opt_flags || {};
  text = (this.currentFlags.adjust || this.currentFlags.preprocess) ?
      sre.Grammar.getInstance().preprocess(text) :
      text;
  if (this.parameters_['translate'] || this.currentFlags.translate) {
    text = sre.Grammar.translateString_(text);
  }
  text = (this.currentFlags.adjust || this.currentFlags.correct) ?
      sre.Grammar.getInstance().correct(text) :
      text;
  this.currentFlags = {};
  return text;
};

/**
 * Parses a state string that can be passed to the grammar.
 * @param {string} stateStr The state string for the grammar.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseState = function(stateStr) {
  var state = {};
  var corrections = stateStr.split(' ');
  for (var i = 0, l = corrections.length; i < l; i++) {
    var corr = corrections[i].split(':');
    var key = corr[0];
    var value = corr[1];
    state[key] = value ? value : true;
  }
  return state;
};

/**
 * Processes the grammar annotations of a rule.
 * @param {string} grammar The grammar annotations.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseInput = function(grammar) {
  var attributes = {};
  var components = grammar.split(':');
  for (var i = 0, l = components.length; i < l; i++) {
    var comp = components[i].split('=');
    var key = comp[0].trim();
    if (comp[1]) {
      attributes[key] = comp[1].trim();
      continue;
    }
    key.match(/^!/) ? attributes[key.slice(1)] = false : attributes[key] = true;
  }
  return attributes;
};

// TODO: The following is temporary and needs a better place.
//
/**
 * Applies a corrective string to the given description text.
 * @param {string} text The original description text.
 * @param {string} correction The correction string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.correctFont_ = function(text, correction) {
  if (!correction || !text) {
    return text;
  }
  correction = sre.Messages.MS_FUNC.FONT_REGEXP(sre.Locale.localFont(correction));
  return text.replace(correction, '');
};

/**
 * Attaches an annotation to a description.
 * @param {string} text The original description text.
 * @param {string} annotation The annotation string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.addAnnotation_ = function(text, annotation) {
  return text + ':' + annotation;
};

sre.Grammar.noTranslateText_ = function(text) {
  if (text.match(new RegExp('^[' + sre.Messages.REGEXP.TEXT + ']+$'))) {
    sre.Grammar.getInstance().currentFlags['translate'] = false;
  }
  return text;
};

sre.Grammar.getInstance().setCorrection('ignoreFont',
                                        sre.Grammar.correctFont_);
sre.Grammar.getInstance().setPreprocessor('annotation',
                                          sre.Grammar.addAnnotation_);
sre.Grammar.getInstance().setPreprocessor('noTranslateText',
                                          sre.Grammar.noTranslateText_);
sre.Grammar.getInstance().setCorrection('ignoreCaps',
                                        sre.Grammar.correctFont_);

<|endoftext|>


<commit_before>/* global define */
(function() {
    'use strict';
    define(['lodash', 'helpers/modal-helpers', 'helpers/osd-helpers'], function(_, modalHelpers, osdHelpers) {

        var disableRepair = true;
        var text = {
            'down': ' DOWN',
            'in': ' IN',
            'out': ' OUT',
            'scrub': ' SCRUB',
            'deep_scrub': ' DEEP SCRUB',
            'repair': ' REPAIR',
            'repairText': '',
            'configText': '',
            'spinner': '',
            'success': ''
        };

        var maxReweight = 100;
        var OSDHostController = function($q, $log, $scope, $routeParams, ClusterService, ServerService, $location, OSDService, $modal, $timeout, RequestTrackingService, PoolService, config) {
            function transformOSDToUI(osd) {
                osd.reweight = Math.min(osd.reweight * maxReweight, maxReweight);
                osd.reweight = Math.max(osd.reweight, 0);
                osd.reweight = Math.round(osd.reweight);
                osd._reweight = angular.copy(osd.reweight);
            }
            $scope.fqdn = $routeParams.fqdn;
            $scope.clusterName = ClusterService.clusterModel.name;
            $scope.breadcrumbs = [{
                    text: 'Manage (' + $scope.clusterName + ')',
                }, {
                    text: 'OSD',
                    href: '#/osd'
                }, {
                    text: 'Host (' + $scope.fqdn + ')',
                    active: true
                }
            ];
            $scope.displayFn = function(id) {
                OSDService.get(id).then(function(_osd) {
                    var modal = $modal({
                        title: 'OSD ' + _osd.id + ' Info',
                        template: 'views/osd-info-modal.html'
                    });
                    PoolService.getList().then(function(pools) {
                        modal.$scope.pairs = osdHelpers.formatOSDData(_osd, pools);
                    });
                });
            };
            $scope.changedFn = function(osd) {
                $log.debug('changed ' + osd.id);
                if (osd.timeout) {
                    $timeout.cancel(osd.timeout);
                    osd.timeout = undefined;
                }
                $log.debug('reweight: ' + osd.reweight);
                if (osd.reweight === '' || osd.reweight === void 0) {
                    osd.hasError = true;
                    return;
                }
                if (_.isNumber(osd.reweight) && (osd.reweight > maxReweight || osd.reweight < 0)) {
                    osd.reweight = angular.copy(osd._reweight);
                    return;
                }
                if (_.isNaN(osd.reweight)) {
                    osd.hasError = true;
                    return;
                }
                osd.hasError = false;
                if (osd.reweight === osd._reweight) {
                    return;
                }
                osd.timeout = $timeout(function() {
                    osd.editing = true;
                    var start = Date.now();
                    var modal = $modal({
                        html: true,
                        title: '',
                        backdrop: 'static',
                        template: 'views/osd-cmd-modal.html',
                        show: false
                    });
                    OSDService.patch(osd.id, {
                        reweight: osd.reweight / maxReweight
                    }).then(function(resp) {
                        /* jshint camelcase: false */
                        var promise = RequestTrackingService.add(resp.data.request_id);
                        var elapsed = Date.now() - start;
                        var timeout = elapsed < config.getAnimationTimeoutMs() ? config.getAnimationTimeoutMs() - elapsed : 0;
                        $timeout(function() {
                            osd.saved = true;
                            promise.then(function() {
                                osd._reweight = angular.copy(osd.reweight);
                                osd.editing = false;
                                osd.saved = false;
                            });
                        }, timeout);
                    }, modalHelpers.makeOnError(modal));

                    $timeout(function() {
                        osd.saved = true;
                        osd.editing = false;
                        $timeout(function() {
                            osd.saved = false;
                        }, config.getAnimationTimeoutMs());
                    }, config.getAnimationTimeoutMs());
                }, config.getEditDebounceMs());
            };

            function generateConfigDropdown(result, handler) {
                result.configDropdown = [];
                if (result.up) {
                    // One can only set an OSD down. The Cluster automatically promotes the OSD
                    // to Up unless the noup flag is set on the cluster
                    result.configDropdown.push({
                        'text': text.down,
                        'id': result.id,
                        'cmd': 'down',
                        'index': result.index,
                        'handler': handler
                    });
                }
                if (result['in']) {
                    result.configDropdown.push({
                        'text': text.out,
                        'id': result.id,
                        'cmd': 'out',
                        'index': result.index,
                        'handler': handler
                    });
                } else {
                    result.configDropdown.push({
                        'text': text['in'],
                        'id': result.id,
                        'cmd': 'in',
                        'index': result.index,
                        'handler': handler
                    });
                }
            }

            function addUIMetadataToOSDData(osd, index) {
                /* jshint camelcase:false */
                _.extend(osd, {
                    index: index,
                    repairText: text.repairText,
                    configText: text.configText,
                    hasError: false,
                    editing: false,
                    saved: false,
                    editDisabled: false
                });
                if (osd.valid_commands.length) {
                    if (disableRepair) {
                        osd.valid_commands = _.filter(osd.valid_commands, function(command) {
                            return command !== 'repair';
                        });
                    }
                    osd.repairDropdown = _.reduce(osd.valid_commands, function(newdropdown, cmd) {
                        newdropdown.push({
                            'text': text[cmd],
                            'id': osd.id,
                            'cmd': cmd,
                            'index': index,
                            'handler': repairClickHandler
                        });
                        return newdropdown;
                    }, []);
                } else {
                    osd.repairDisabled = true;
                }
                generateConfigDropdown(osd, configClickHandler);
                transformOSDToUI(osd);
            }

            function requestRepairPermission(repairFn) {
                return function($event, id, cmd, index) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    if (cmd === 'repair') {
                        var modal = $modal({
                            html: true,
                            title: ' Repair OSD ' + id + '?',
                            backdrop: 'static',
                            template: 'views/osd-repair-warn-modal.html',
                            content: 'Please ensure you have checked the cluster logs for scrub output marked Error to determine if this is the correct OSD to run the repair on. Failure to do so may result in the permanent loss of data.',
                            show: true
                        });
                        modal.$scope.acceptFn = function() {
                            modal.$scope.$hide();
                            repairFn($event, id, cmd, index);
                        };
                    } else {
                        repairFn($event, id, cmd, index);
                    }
                };
            }

            function makeCommandHandler(buttonLabel) {
                return function($event, id, cmd, index) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    $log.debug('CLICKED osd ' + id + ' command ' + cmd);
                    var osd = $scope.services.osds[index];
                    osd.disabled = true;
                    osd[buttonLabel] = text.spinner;
                    var start = Date.now();
                    var modal = $modal({
                        html: true,
                        title: '',
                        backdrop: 'static',
                        template: 'views/osd-cmd-modal.html',
                        show: false
                    });
                    OSDService[cmd].call(OSDService, id).then(function success(resp) {
                        /* jshint camelcase: false */
                        var promise = RequestTrackingService.add(resp.data.request_id);
                        var elapsed = Date.now() - start;
                        var timeout = (elapsed < config.getAnimationTimeoutMs()) ? config.getAnimationTimeoutMs() - elapsed : 0;
                        modal.$scope.disableClose = true;
                        modal.$scope._hide = function() {
                            modal.$scope.$hide();
                        };
                        $timeout(function() {
                            osd[buttonLabel] = text.success;
                            $timeout(function() {
                                osd[buttonLabel] = text[buttonLabel];
                                osd.disabled = false;
                                promise.then(function() {
                                    OSDService.get(id).then(function(_osd) {
                                        // refresh osd state
                                        transformOSDToUI(_osd);
                                        _.extend(osd, _osd);
                                        osd.repairDisabled = !osd.up;
                                        osd.editDisabled = !osd.up || !osd. in ;
                                        generateConfigDropdown(osd, configClickHandler);
                                    });
                                });
                            }, config.getAnimationTimeoutMs());
                        }, timeout);
                    }, modalHelpers.makeOnError(modal, function cleanup() {
                        osd[buttonLabel] = text[buttonLabel];
                        osd.disabled = false;
                    }));
                    return false;
                };
            }

            var configClickHandler = makeCommandHandler('configText');
            var repairClickHandler = requestRepairPermission(makeCommandHandler('repairText'));

            ServerService.get($scope.fqdn).then(function(server) {
                $scope.server = server;
                var r = _.reduce(_.sortBy(server.services, function(service) {
                    var id = parseInt(service.id, 10);
                    return _.isNaN(id) ? 0 : id;
                }), function(results, service) {
                    if (service.type === 'osd') {
                        var osd = {
                            id: service.id,
                            running: true
                        };
                        results.osds.push(osd);
                        results.ids.push(osd.id);
                    }
                    return results;
                }, {
                    osds: [],
                    ids: []
                });
                $q.all(OSDService.getSet(r.ids)).then(function(results) {
                    _.each(results, function(result, index) {
                        addUIMetadataToOSDData(result, index);
                        r.osds[index] = _.extend(r.osds[index], result);
                    });
                    $scope.services = {
                        osds: r.osds
                    };
                    $scope.up = true;
                });
            });

        };
        return ['$q', '$log', '$scope', '$routeParams', 'ClusterService', 'ServerService', '$location', 'OSDService', '$modal', '$timeout', 'RequestTrackingService', 'PoolService', 'ConfigurationService', OSDHostController];
    });
})();
<commit_msg>Fix a bug<commit_after>/* global define */
(function() {
    'use strict';
    define(['lodash', 'helpers/modal-helpers', 'helpers/osd-helpers'], function(_, modalHelpers, osdHelpers) {

        var disableRepair = true;
        var text = {
            'down': ' DOWN',
            'in': ' IN',
            'out': ' OUT',
            'scrub': ' SCRUB',
            'deep_scrub': ' DEEP SCRUB',
            'repair': ' REPAIR',
            'repairText': '',
            'configText': '',
            'spinner': '',
            'success': ''
        };

        var maxReweight = 100;
        var OSDHostController = function($q, $log, $scope, $routeParams, ClusterService, ServerService, $location, OSDService, $modal, $timeout, RequestTrackingService, PoolService, config) {
            function formatOSDForUI(osd) {
                osd.reweight = Math.min(osd.reweight * maxReweight, maxReweight);
                osd.reweight = Math.max(osd.reweight, 0);
                osd.reweight = Math.round(osd.reweight);
                osd._reweight = angular.copy(osd.reweight);
            }
            $scope.fqdn = $routeParams.fqdn;
            $scope.clusterName = ClusterService.clusterModel.name;
            $scope.breadcrumbs = [{
                    text: 'Manage (' + $scope.clusterName + ')',
                }, {
                    text: 'OSD',
                    href: '#/osd'
                }, {
                    text: 'Host (' + $scope.fqdn + ')',
                    active: true
                }
            ];
            $scope.displayFn = function(id) {
                OSDService.get(id).then(function(_osd) {
                    var modal = $modal({
                        title: 'OSD ' + _osd.id + ' Info',
                        template: 'views/osd-info-modal.html'
                    });
                    PoolService.getList().then(function(pools) {
                        modal.$scope.pairs = osdHelpers.formatOSDData(_osd, pools);
                    });
                });
            };
            $scope.changedFn = function(osd) {
                $log.debug('changed ' + osd.id);
                if (osd.timeout) {
                    $timeout.cancel(osd.timeout);
                    osd.timeout = undefined;
                }
                $log.debug('reweight: ' + osd.reweight);
                if (osd.reweight === '' || osd.reweight === void 0) {
                    osd.hasError = true;
                    return;
                }
                if (_.isNumber(osd.reweight) && (osd.reweight > maxReweight || osd.reweight < 0)) {
                    osd.reweight = angular.copy(osd._reweight);
                    return;
                }
                if (_.isNaN(osd.reweight)) {
                    osd.hasError = true;
                    return;
                }
                osd.hasError = false;
                if (osd.reweight === osd._reweight) {
                    return;
                }
                osd.timeout = $timeout(function() {
                    osd.editing = true;
                    var start = Date.now();
                    var modal = $modal({
                        html: true,
                        title: '',
                        backdrop: 'static',
                        template: 'views/osd-cmd-modal.html',
                        show: false
                    });
                    OSDService.patch(osd.id, {
                        reweight: osd.reweight / maxReweight
                    }).then(function(resp) {
                        /* jshint camelcase: false */
                        var promise = RequestTrackingService.add(resp.data.request_id);
                        var elapsed = Date.now() - start;
                        var timeout = elapsed < config.getAnimationTimeoutMs() ? config.getAnimationTimeoutMs() - elapsed : 0;
                        $timeout(function() {
                            osd.saved = true;
                            promise.then(function() {
                                osd._reweight = angular.copy(osd.reweight);
                                osd.editing = false;
                                osd.saved = false;
                            });
                        }, timeout);
                    }, modalHelpers.makeOnError(modal));

                    $timeout(function() {
                        osd.saved = true;
                        osd.editing = false;
                        $timeout(function() {
                            osd.saved = false;
                        }, config.getAnimationTimeoutMs());
                    }, config.getAnimationTimeoutMs());
                }, config.getEditDebounceMs());
            };

            function generateConfigDropdown(result, handler) {
                result.configDropdown = [];
                if (result.up) {
                    // One can only set an OSD down. The Cluster automatically promotes the OSD
                    // to Up unless the noup flag is set on the cluster
                    result.configDropdown.push({
                        'text': text.down,
                        'id': result.id,
                        'cmd': 'down',
                        'index': result.index,
                        'handler': handler
                    });
                }
                if (result['in']) {
                    result.configDropdown.push({
                        'text': text.out,
                        'id': result.id,
                        'cmd': 'out',
                        'index': result.index,
                        'handler': handler
                    });
                } else {
                    result.configDropdown.push({
                        'text': text['in'],
                        'id': result.id,
                        'cmd': 'in',
                        'index': result.index,
                        'handler': handler
                    });
                }
            }

            function addUIMetadataToOSDData(osd, index) {
                /* jshint camelcase:false */
                _.extend(osd, {
                    index: index,
                    repairText: text.repairText,
                    configText: text.configText,
                    hasError: false,
                    editing: false,
                    saved: false,
                    editDisabled: false
                });
                if (osd.valid_commands.length) {
                    if (disableRepair) {
                        osd.valid_commands = _.filter(osd.valid_commands, function(command) {
                            return command !== 'repair';
                        });
                    }
                    osd.repairDropdown = _.reduce(osd.valid_commands, function(newdropdown, cmd) {
                        newdropdown.push({
                            'text': text[cmd],
                            'id': osd.id,
                            'cmd': cmd,
                            'index': index,
                            'handler': repairClickHandler
                        });
                        return newdropdown;
                    }, []);
                } else {
                    osd.repairDisabled = true;
                }
                generateConfigDropdown(osd, configClickHandler);
                formatOSDForUI(osd);
            }

            function requestRepairPermission(repairFn) {
                return function($event, id, cmd, index) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    if (cmd === 'repair') {
                        var modal = $modal({
                            html: true,
                            title: ' Repair OSD ' + id + '?',
                            backdrop: 'static',
                            template: 'views/osd-repair-warn-modal.html',
                            content: 'Please ensure you have checked the cluster logs for scrub output marked Error to determine if this is the correct OSD to run the repair on. Failure to do so may result in the permanent loss of data.',
                            show: true
                        });
                        modal.$scope.acceptFn = function() {
                            modal.$scope.$hide();
                            repairFn($event, id, cmd, index);
                        };
                    } else {
                        repairFn($event, id, cmd, index);
                    }
                };
            }

            function makeCommandHandler(buttonLabel) {
                return function($event, id, cmd, index) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    $log.debug('CLICKED osd ' + id + ' command ' + cmd);
                    var osd = $scope.services.osds[index];
                    osd.disabled = true;
                    osd[buttonLabel] = text.spinner;
                    var start = Date.now();
                    var modal = $modal({
                        html: true,
                        title: '',
                        backdrop: 'static',
                        template: 'views/osd-cmd-modal.html',
                        show: false
                    });
                    OSDService[cmd].call(OSDService, id).then(function success(resp) {
                        /* jshint camelcase: false */
                        var promise = RequestTrackingService.add(resp.data.request_id);
                        var elapsed = Date.now() - start;
                        var timeout = (elapsed < config.getAnimationTimeoutMs()) ? config.getAnimationTimeoutMs() - elapsed : 0;
                        modal.$scope.disableClose = true;
                        modal.$scope._hide = function() {
                            modal.$scope.$hide();
                        };
                        $timeout(function() {
                            osd[buttonLabel] = text.success;
                            $timeout(function() {
                                osd[buttonLabel] = text[buttonLabel];
                                osd.disabled = false;
                                promise.then(function() {
                                    OSDService.get(id).then(function(_osd) {
                                        // refresh osd state
                                        formatOSDForUI(_osd);
                                        _.extend(osd, _osd);
                                        osd.repairDisabled = !osd.up;
                                        osd.editDisabled = !osd.up || !osd['in'];
                                        generateConfigDropdown(osd, configClickHandler);
                                    });
                                });
                            }, config.getAnimationTimeoutMs());
                        }, timeout);
                    }, modalHelpers.makeOnError(modal, function cleanup() {
                        osd[buttonLabel] = text[buttonLabel];
                        osd.disabled = false;
                    }));
                    return false;
                };
            }

            var configClickHandler = makeCommandHandler('configText');
            var repairClickHandler = requestRepairPermission(makeCommandHandler('repairText'));

            ServerService.get($scope.fqdn).then(function(server) {
                $scope.server = server;
                var r = _.reduce(_.sortBy(server.services, function(service) {
                    var id = parseInt(service.id, 10);
                    return _.isNaN(id) ? 0 : id;
                }), function(results, service) {
                    if (service.type === 'osd') {
                        var osd = {
                            id: service.id,
                            running: true
                        };
                        results.osds.push(osd);
                        results.ids.push(osd.id);
                    }
                    return results;
                }, {
                    osds: [],
                    ids: []
                });
                $q.all(OSDService.getSet(r.ids)).then(function(results) {
                    _.each(results, function(result, index) {
                        addUIMetadataToOSDData(result, index);
                        r.osds[index] = _.extend(r.osds[index], result);
                    });
                    $scope.services = {
                        osds: r.osds
                    };
                    $scope.up = true;
                });
            });

        };
        return ['$q', '$log', '$scope', '$routeParams', 'ClusterService', 'ServerService', '$location', 'OSDService', '$modal', '$timeout', 'RequestTrackingService', 'PoolService', 'ConfigurationService', OSDHostController];
    });
})();
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018. Stephan Mahieu
 *
 * This file is subject to the terms and conditions defined in
 * file 'LICENSE', which is part of this source code package.
 */

//import {DateUtil} from '../common/DateUtil.js';
//import {XmlUtil}  from '../common/XmlUtil.js';

'use strict';

browser.runtime.onMessage.addListener(fhcEvent=>{
    if (fhcEvent.eventType) {
        switch (fhcEvent.eventType) {
            case 888:
                if (fhcEvent.interfaceThemeChanged) {
                    // options have changed, reload
                    OptionsUtil.getInterfaceTheme().then(res => {
                        ThemeUtil.switchTheme(res);
                    });
                }
                break;
            case 666:
                browser.windows.getCurrent({populate: false}).then((window)=>{
                    WindowUtil.closePopupByID(window.id);
                });
                break;
        }
    }
});

document.addEventListener("DOMContentLoaded", function(/*event*/) {
    OptionsUtil.getInterfaceTheme().then(res=>{ThemeUtil.switchTheme(res);});

    document.getElementById("buttonExport").addEventListener("click", handleExport);
    document.getElementById("buttonClose").addEventListener("click", WindowUtil.closeThisPopup);
    document.addEventListener("keyup", onKeyClicked);

    // start the export immediately and display the download link
    handleExport();
});

function handleExport(/*evt*/) {
    let timeStarted = showBusy();

    let req = indexedDB.open(DbConst.DB_NAME, DbConst.DB_VERSION);
    req.onerror = function (/*event*/) {
        hideBusy(timeStarted);
        console.error("Database open error", this.error);
    };
    req.onsuccess = function (event) {
        let db = event.target.result;
        //console.log("Database opened successfully.");

        let textEntries = [];
        let multilines = [];

        let count = 0;
        let objStore = db.transaction(DbConst.DB_STORE_TEXT, "readonly").objectStore(DbConst.DB_STORE_TEXT);
        let cursorReq = objStore.index(DbConst.DB_TEXT_IDX_LAST).openCursor(null, "prev");
        cursorReq.onsuccess = function(evt) {
            let cursor = evt.target.result;
            if (cursor) {
                let fhcEntry = cursor.value;
                //console.log("Entry [" + cursor.key + "] name:[" + fhcEntry.name + "] value:[" + fhcEntry.value + "] used:[" + fhcEntry.used + "] host:" + fhcEntry.host + "] type:[" + fhcEntry.type + "} KEY=[" + fhcEntry.fieldkey + "]");

                count += 1;
                if (fhcEntry.type === 'input' || fhcEntry.type === 'input') {
                    textEntries.push({
                        name: fhcEntry.name,
                        value: fhcEntry.value,
                        used: fhcEntry.used,
                        first: fhcEntry.first,
                        last: fhcEntry.last,
                        /* new */
                        type: fhcEntry.type,
                        host: fhcEntry.host,
                        url: fhcEntry.uri,
                        pagetitle: fhcEntry.pagetitle
                    });
                } else {
                    multilines.push({
                        id: "",
                        name: fhcEntry.name,
                        type: fhcEntry.type,
                        formid: "",
                        host: fhcEntry.host,
                        url: fhcEntry.uri,
                        first: fhcEntry.first,
                        last: fhcEntry.last,
                        content: fhcEntry.value,
                        /* new */
                        used: fhcEntry.used,
                        pagetitle: fhcEntry.pagetitle
                    });
                }

                cursor.continue();
            }
            else {
                hideBusy(timeStarted);
                //console.log("No more entries!");
                //console.log("Exporting " + textEntries.length + " text-entries and " + multilines.length + " multiline entries");

                document.getElementById('count-text').textContent = textEntries.length;
                document.getElementById('count-multiline').textContent = multilines.length;

                let content = XmlUtil.serializeToXMLString(textEntries, multilines);
                setDownloadLink(content);
            }
        }
    };

}

function onKeyClicked(event) {
    const keyName = event.key;

    if (keyName === 'Escape') {
        if (WindowUtil.isModalDialogActive()) {
            WindowUtil.doCancelModalDialog();
        } else {
            WindowUtil.closeThisPopup();
        }
    }
}

function setDownloadLink(content) {
    let alink = document.getElementById('link');

    alink.setAttribute('href', 'data:application/xml;charset=utf-8,' + encodeURIComponent(content));
    alink.setAttribute('download', "formhistory.xml");

    alink.style.display = "inline";
    document.getElementById('linkInfo').style.display = "block";
}

function showBusy() {
    document.querySelector('#overlaystatus').classList.add('spinner');
    document.querySelector('#overlaystatus').style.display = 'block';
    return new Date();
}

function hideBusy(timeStarted) {
    // the busy spinner is visible for a minimum amount of time to avoid flickering so the user gets a chance
    // to see the spinner and read the text
    const minVisibleDisplayTime = 1200;
    let displayPause = 0;
    let timeElapsed = (new Date()) - timeStarted;
    if (timeElapsed < minVisibleDisplayTime) {
        displayPause = minVisibleDisplayTime - timeElapsed;
    }
    setTimeout(() => {
        document.querySelector('#overlaystatus').style.display = 'none';
        document.querySelector('#overlaystatus').classList.remove('spinner');
    }, displayPause);
}
<commit_msg>Remove duplicate if condition<commit_after>/*
 * Copyright (c) 2018. Stephan Mahieu
 *
 * This file is subject to the terms and conditions defined in
 * file 'LICENSE', which is part of this source code package.
 */

//import {DateUtil} from '../common/DateUtil.js';
//import {XmlUtil}  from '../common/XmlUtil.js';

'use strict';

browser.runtime.onMessage.addListener(fhcEvent=>{
    if (fhcEvent.eventType) {
        switch (fhcEvent.eventType) {
            case 888:
                if (fhcEvent.interfaceThemeChanged) {
                    // options have changed, reload
                    OptionsUtil.getInterfaceTheme().then(res => {
                        ThemeUtil.switchTheme(res);
                    });
                }
                break;
            case 666:
                browser.windows.getCurrent({populate: false}).then((window)=>{
                    WindowUtil.closePopupByID(window.id);
                });
                break;
        }
    }
});

document.addEventListener("DOMContentLoaded", function(/*event*/) {
    OptionsUtil.getInterfaceTheme().then(res=>{ThemeUtil.switchTheme(res);});

    document.getElementById("buttonExport").addEventListener("click", handleExport);
    document.getElementById("buttonClose").addEventListener("click", WindowUtil.closeThisPopup);
    document.addEventListener("keyup", onKeyClicked);

    // start the export immediately and display the download link
    handleExport();
});

function handleExport(/*evt*/) {
    let timeStarted = showBusy();

    let req = indexedDB.open(DbConst.DB_NAME, DbConst.DB_VERSION);
    req.onerror = function (/*event*/) {
        hideBusy(timeStarted);
        console.error("Database open error", this.error);
    };
    req.onsuccess = function (event) {
        let db = event.target.result;
        //console.log("Database opened successfully.");

        let textEntries = [];
        let multilines = [];

        let count = 0;
        let objStore = db.transaction(DbConst.DB_STORE_TEXT, "readonly").objectStore(DbConst.DB_STORE_TEXT);
        let cursorReq = objStore.index(DbConst.DB_TEXT_IDX_LAST).openCursor(null, "prev");
        cursorReq.onsuccess = function(evt) {
            let cursor = evt.target.result;
            if (cursor) {
                let fhcEntry = cursor.value;
                //console.log("Entry [" + cursor.key + "] name:[" + fhcEntry.name + "] value:[" + fhcEntry.value + "] used:[" + fhcEntry.used + "] host:" + fhcEntry.host + "] type:[" + fhcEntry.type + "} KEY=[" + fhcEntry.fieldkey + "]");

                count += 1;
                if (fhcEntry.type === 'input') {
                    textEntries.push({
                        name: fhcEntry.name,
                        value: fhcEntry.value,
                        used: fhcEntry.used,
                        first: fhcEntry.first,
                        last: fhcEntry.last,
                        /* new */
                        type: fhcEntry.type,
                        host: fhcEntry.host,
                        url: fhcEntry.uri,
                        pagetitle: fhcEntry.pagetitle
                    });
                } else {
                    multilines.push({
                        id: "",
                        name: fhcEntry.name,
                        type: fhcEntry.type,
                        formid: "",
                        host: fhcEntry.host,
                        url: fhcEntry.uri,
                        first: fhcEntry.first,
                        last: fhcEntry.last,
                        content: fhcEntry.value,
                        /* new */
                        used: fhcEntry.used,
                        pagetitle: fhcEntry.pagetitle
                    });
                }

                cursor.continue();
            }
            else {
                hideBusy(timeStarted);
                //console.log("No more entries!");
                //console.log("Exporting " + textEntries.length + " text-entries and " + multilines.length + " multiline entries");

                document.getElementById('count-text').textContent = textEntries.length;
                document.getElementById('count-multiline').textContent = multilines.length;

                let content = XmlUtil.serializeToXMLString(textEntries, multilines);
                setDownloadLink(content);
            }
        }
    };

}

function onKeyClicked(event) {
    const keyName = event.key;

    if (keyName === 'Escape') {
        if (WindowUtil.isModalDialogActive()) {
            WindowUtil.doCancelModalDialog();
        } else {
            WindowUtil.closeThisPopup();
        }
    }
}

function setDownloadLink(content) {
    let alink = document.getElementById('link');

    alink.setAttribute('href', 'data:application/xml;charset=utf-8,' + encodeURIComponent(content));
    alink.setAttribute('download', "formhistory.xml");

    alink.style.display = "inline";
    document.getElementById('linkInfo').style.display = "block";
}

function showBusy() {
    document.querySelector('#overlaystatus').classList.add('spinner');
    document.querySelector('#overlaystatus').style.display = 'block';
    return new Date();
}

function hideBusy(timeStarted) {
    // the busy spinner is visible for a minimum amount of time to avoid flickering so the user gets a chance
    // to see the spinner and read the text
    const minVisibleDisplayTime = 1200;
    let displayPause = 0;
    let timeElapsed = (new Date()) - timeStarted;
    if (timeElapsed < minVisibleDisplayTime) {
        displayPause = minVisibleDisplayTime - timeElapsed;
    }
    setTimeout(() => {
        document.querySelector('#overlaystatus').style.display = 'none';
        document.querySelector('#overlaystatus').classList.remove('spinner');
    }, displayPause);
}
<|endoftext|>


<commit_before>(function(root) {

  function bufferToArrayBuffer(buffer) {
    var ab = new ArrayBuffer(buffer.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buffer.length; ++i) {
      view[i] = buffer[i];
    }
    return ab;
  }

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = bufferToArrayBuffer;
    }
    exports.bufferToArrayBuffer = bufferToArrayBuffer;
  } else if (typeof define === 'function' && define.amd) {
    define([], function() {
      return bufferToArrayBuffer;
    });
  } else {
    root.bufferToArrayBuffer = bufferToArrayBuffer;
  }

})(this);
<commit_msg>Use buffer.buffer property<commit_after>(function(root) {
  var isArrayBufferSupported = !!(new Buffer(0).buffer);

  var bufferToArrayBuffer = isArrayBufferSupported ? bufferToArrayBufferSlice : bufferToArrayBufferCycle;

  function bufferToArrayBufferSlice (buffer) {
    return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
  }

  function bufferToArrayBufferCycle (buffer) {
    var ab = new ArrayBuffer(buffer.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buffer.length; ++i) {
      view[i] = buffer[i];
    }
    return ab;
  }

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = bufferToArrayBuffer;
    }
    exports.bufferToArrayBuffer = bufferToArrayBuffer;
  } else if (typeof define === 'function' && define.amd) {
    define([], function() {
      return bufferToArrayBuffer;
    });
  } else {
    root.bufferToArrayBuffer = bufferToArrayBuffer;
  }

})(this);
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class DropdownContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isClicked: false
    };
  }

  onClick = () => {
    this.setState({
      isClicked: !this.state.isClicked
    });
  };
  handleBodyClick = () => {
    this.setState({ isClicked: false });
  };

  componentDidUpdate() {
    document
      .getElementById('root')
      .addEventListener('click', this.handleBodyClick);
  }

  componentWillUpdate() {
    document
      .getElementById('root')
      .removeEventListener('click', this.handleBodyClick);
  }

  render() {
    return (

        <DropdownTrigger
          isClicked={this.state.isClicked}
          onSelect={() => this.onClick()}
        />
        <DropdownItems visible={this.state.isClicked} />

    );
  }
}

class DropdownTrigger extends Component {
  render() {
    const triggerStyle = this.props.isClicked
      ? { backgroundColor: '#EEEEEE', width: '86.5px', display: 'flex' }
      : {};
    return (

          Dropdown

    );
  }
}
class DropdownItems extends Component {
  render() {
    const itemContent = ['Action', 'Another action', 'Something else here'];
    const itemStyle = {
      marginLeft: '0px',
      marginTop: '4px',
      marginRight: '0px',
      marginBottom: '4px',
      paddingLeft: '15px',
      verticalAlign: 'middle',
      paddingTop: '4px',
      paddingBottom: '4px'
    };
    if (this.props.visible) {
      return (

          {itemContent.map((value, key) => {
            return (

{value}

            );
          })}

Separated link

      );
    } else {
      return
;
    }
  }
}

export default DropdownContainer;
<commit_msg>cursor pointer issue solved<commit_after>import React, { Component } from 'react';

class DropdownContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isClicked: false
    };
  }

  onClick = () => {
    this.setState({
      isClicked: !this.state.isClicked
    });
  };
  handleBodyClick = () => {
    this.setState({ isClicked: false });
  };

  componentDidUpdate() {
    document
      .getElementById('root')
      .addEventListener('click', this.handleBodyClick);
  }

  componentWillUpdate() {
    document
      .getElementById('root')
      .removeEventListener('click', this.handleBodyClick);
  }

  render() {
    return (

        <DropdownTrigger
          isClicked={this.state.isClicked}
          onSelect={() => this.onClick()}
        />
        <DropdownItems visible={this.state.isClicked} />

    );
  }
}

class DropdownTrigger extends Component {
  render() {
    const triggerStyle = this.props.isClicked
      ? {
          backgroundColor: '#EEEEEE',
          width: '86.5px',
          cursor: 'pointer',
          display: 'flex'
        }
      : { cursor: 'pointer' };
    return (

          Dropdown

    );
  }
}
class DropdownItems extends Component {
  render() {
    const itemContent = ['Action', 'Another action', 'Something else here'];
    const itemStyle = {
      marginLeft: '0px',
      marginTop: '4px',
      marginRight: '0px',
      marginBottom: '4px',
      paddingLeft: '15px',
      verticalAlign: 'middle',
      paddingTop: '4px',
      paddingBottom: '4px'
    };
    if (this.props.visible) {
      return (

          {itemContent.map((value, key) => {
            return (

{value}

            );
          })}

Separated link

      );
    } else {
      return
;
    }
  }
}

export default DropdownContainer;
<|endoftext|>


<commit_before>const mongoose = require('mongoose');

const Project = mongoose.model('Project');
const Task = mongoose.model('Task');

function getAllChildren(myID, projects) {
  // TODO: Possible duplication of code: to reduce
  if (myID === undefined) {
    return [];
  }
  const children = [];
  const recursive = id => {
    projects.forEach(project => {
      if (id === project.parent_id) {
        children.push(project._id.toString());
        recursive(project._id);
      }
    });
  };
  recursive(myID);
  return children;
}

exports.add = async (req, res) => {
  req.body.author = req.user._id; // eslint-disable-line no-underscore-dangle
  const project = await new Project(req.body).save();
  res.json({ project });
};

exports.update = async (req, res) => {
  const projects = await Project.find({});
  const children = getAllChildren(req.params.id, projects);
  const isChild = children.indexOf(req.body.parentID.toString()) !== -1;
  if (isChild) {
    res.json({
      error:
        'Could not update the project. Child project can not be chosen as a parent'
    });
    return;
  }
  await Project.findById(req.params.id, (err, data) => {
    data.name = req.body.name; // eslint-disable-line no-param-reassign
    // if (data.parent_id !== req.body.parentID) {
    //   data.parent_id = req.body.parentID; // eslint-disable-line no-param-reassign
    // }
    data.save();
    res.json({ project: data });
  });
};

exports.addTime = async (req, res) => {
  await Project.findById(req.body.id, (err, data) => {
    data.timeSpent += req.body.time; // eslint-disable-line no-param-reassign
    data.save();
    res.json({ timeAdded: true });
  });
};

exports.getProjects = async (req, res) => {
  const projectsList = await Project.find({
    author: req.user._id
  }).sort({ name: 1 });

  res.send({ projectsList });
};

exports.deleteProject = (req, res) => {
  Task.deleteMany(
    {
      project: req.body.id
    },
    err => {
      if (err) {
        console.log(err);
      }
    }
  );
  Project.findByIdAndRemove(req.body.id, () => {
    res.json({ deleted: true });
  });
};

exports.toggleDone = async (req, res) => {
  await Project.findById(req.body.id, (err, project) => {
    project.done = !project.done; // eslint-disable-line no-param-reassign
    project.updated = new Date(); // eslint-disable-line no-param-reassign
    project.save();
    res.json({ done: project.done });
  });
};
<commit_msg>dont let add project to the archived parents<commit_after>const mongoose = require('mongoose');

const Project = mongoose.model('Project');
const Task = mongoose.model('Task');

function getAllChildren(myID, projects) {
  // TODO: Possible duplication of code: to reduce
  if (myID === undefined) {
    return [];
  }
  const children = [];
  const recursive = id => {
    projects.forEach(project => {
      if (id === project.parent_id) {
        children.push(project._id.toString());
        recursive(project._id);
      }
    });
  };
  recursive(myID);
  return children;
}

function checkIfAnyParentIsDone(projects, id) {
  let result = false;
  function recursive(parentID) {
    projects.forEach(project => {
      if (project.id === parentID && project.done === true) {
        result = true;
      } else if (
        project.id === parentID &&
        project.done !== true &&
        project.parent_id !== '' &&
        result !== true
      ) {
        recursive(project.parent_id);
      }
    });
  }
  recursive(id);
  return result;
}

exports.add = async (req, res) => {
  req.body.author = req.user._id; // eslint-disable-line no-underscore-dangle
  const projects = await Project.find({});
  const hasArchivedParents = checkIfAnyParentIsDone(
    projects,
    req.body.parent_id
  );
  if (hasArchivedParents) {
    res.json({
      error: 'Can not add children to the archived project'
    });
  } else {
    const project = await new Project(req.body).save();
    res.json({ project });
  }
};

exports.update = async (req, res) => {
  const projects = await Project.find({});
  const children = getAllChildren(req.params.id, projects);
  const isChild = children.indexOf(req.body.parentID.toString()) !== -1;
  if (isChild) {
    res.json({
      error:
        'Could not update the project. Child project can not be chosen as a parent'
    });
    return;
  }
  await Project.findById(req.params.id, (err, data) => {
    data.name = req.body.name; // eslint-disable-line no-param-reassign
    // if (data.parent_id !== req.body.parentID) {
    //   data.parent_id = req.body.parentID; // eslint-disable-line no-param-reassign
    // }
    data.save();
    res.json({ project: data });
  });
};

exports.addTime = async (req, res) => {
  await Project.findById(req.body.id, (err, data) => {
    data.timeSpent += req.body.time; // eslint-disable-line no-param-reassign
    data.save();
    res.json({ timeAdded: true });
  });
};

exports.getProjects = async (req, res) => {
  const projectsList = await Project.find({
    author: req.user._id
  }).sort({ name: 1 });

  res.send({ projectsList });
};

exports.deleteProject = (req, res) => {
  Task.deleteMany(
    {
      project: req.body.id
    },
    err => {
      if (err) {
        console.log(err);
      }
    }
  );
  Project.findByIdAndRemove(req.body.id, () => {
    res.json({ deleted: true });
  });
};

exports.toggleDone = async (req, res) => {
  await Project.findById(req.body.id, (err, project) => {
    project.done = !project.done; // eslint-disable-line no-param-reassign
    project.updated = new Date(); // eslint-disable-line no-param-reassign
    project.save();
    res.json({ done: project.done });
  });
};
<|endoftext|>


<commit_before>var clc = require('cli-color');
var maxNickLen = 12;
var fileBuf = 4096; // how many characters of file to remember
var path = require('path');
var myNick = "FruitieX";
var hilight_re = new RegExp(".*" + myNick + ".*", 'i');
var ansi_escape_re = /\x1b[^m]*m/;

var separatorColor = clc.xterm(239);
var numColor = clc.xterm(232).bgXterm(255);
var chanColor = clc.xterm(255).bgXterm(239);
var myNickColor = 1;
var hilightColor = 3;

// we need this in global scope so we can remove the event listeners!
var out;
var openChan = function(filePath) {
	var outFile = filePath + '/out';
	var inFile = filePath + '/in';
	var file = require('fs').readFileSync(outFile, 'utf8');

	var bn = path.basename(filePath);
	var num_s = ' ' + bn.substring(0, bn.indexOf('_')) + ' ';
	var num = numColor(num_s);
	var chan_s = ' ' + bn.substring(bn.indexOf('_') + 1, bn.length) + ' ';
	var chan = chanColor(chan_s);

	var printLine = function(line) {
		var hilight = false;

		// clear channel name
		process.stdout.write('\r' + Array(num_s.length + chan_s.length + 1).join(' ') + '\r');

		// remove timestamps
		line = line.replace(/^([^ ]+ ){2}/, '');
		line = line.split(' ');
		// remove <> around nick
		var nick = line[0].substring(1, line[0].length - 1);

		if(nick === myNick) {
			clrnick = myNickColor;
		} else {
			// nick color, avoids dark colors
			var clrnick = 0;
			for(var i = 0; i < nick.length; i++) {
				clrnick += nick.charCodeAt(i);
			}
			clrnick = Math.pow(clrnick, 2) + clrnick * 2;
			clrnick = clrnick % 255;
			switch(clrnick) {
				case 18: case 22: case 23: case 24:
					clrnick += 3; break;
				case 52: case 53: case 54: case 55: case 56: case 57: case 88: case 89:
					clrnick += 6; break;
				case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239:
					clrnick += 8; break;
				case 0: case 8: case 19: case 22:
					clrnick++; break;
			}
		}

		// limit nicklen
		nick = nick.substr(0, maxNickLen);
		// align nicks
		process.stdout.write(Array(maxNickLen - nick.length + 1).join(' '));
		process.stdout.write(clc.xterm(clrnick)(nick) + separatorColor(':'));
		process.stdout.write(' ');

		// remove nick from line array, now contains space separated text message
		line.shift();
		line = line.join(' ');
		line = line.replace(ansi_escape_re, '');

		if(line.match(hilight_re))
			hilight = true;

		var textColor = 15;
		if (nick === myNick)
			textColor = myNickColor;
		else if (hilight)
			textColor = hilightColor;

		// separator takes up 1 char + whitespace
		var availWidth = process.stdout.columns - maxNickLen - 2;

		var wrappedChars = 0;
		var i = 0;

		while(i * availWidth - wrappedChars < line.length) {
			var start = i * availWidth - wrappedChars;
			var curLine = line.substr(start, availWidth);
			// remove leading space on next line
			curLine.replace(/^\s+/, '');
			// line wrap at word boundary only if there is whitespace on this line
			if(start + availWidth < line.length && curLine.lastIndexOf(' ') !== -1) {
				curLine = curLine.slice(0, curLine.lastIndexOf(' '));
				// remove whitespace
				wrappedChars--;
			}

			wrappedChars += availWidth - curLine.length;

			// empty space on line wrap
			if (i > 0)
				process.stdout.write(Array(process.stdout.columns - availWidth + 1).join(' '));

			process.stdout.write(clc.xterm(textColor)(curLine));
			process.stdout.write('\n');
			i++;
		}

		// print channel name again
		process.stdout.write(num + chan + ' ');
	};

	// log entire file
	var printFile = function(file) {
		var start = 0;
		while (start < file.length) {
			var end = file.indexOf('\n', start);
			if(end === -1)
				break;
			printLine(file.substring(start, end));
			start = end + 1;
		}
	};

	// limit file to size fileBuf
	if(file.length >= fileBuf) {
		file = file.substr(file.length - fileBuf, file.length);
		file = file.substr(file.indexOf("\n") + 1, file.length);
	}

	// set raw mode
	var stdin = process.stdin;
	stdin.setRawMode(true);
	stdin.resume();
	stdin.setEncoding('utf8');

	// handle 'q', 'ctrl-c' by quitting
	stdin.on('data', function(key) {
		if(key == 'q' || key == '\u0003') process.exit();
	});

	// clear terminal and print
	process.stdout.write('\u001B[2J\u001B[0;0f');
	printFile(file);

	// watch file
	Tail = require('tail').Tail;
	out = new Tail(outFile);

	out.on('line', function(data) {
		file += data + '\n';
		// limit file to size fileBuf
		if(file.length >= fileBuf) {
			file = file.substr(file.length - fileBuf, file.length);
			file = file.substr(file.indexOf("\n") + 1, file.length);
		}

		// print the line
		printLine(data);
	});

	process.stdout.on('resize', function() {
		process.stdout.write('\u001B[2J\u001B[0;0f');
		printFile(file);
	});
};

// TODO: changing channels?
var currentChan = process.argv[2];
openChan(process.argv[2]);
<commit_msg>if no number found don't print it<commit_after>var clc = require('cli-color');
var maxNickLen = 12;
var fileBuf = 4096; // how many characters of file to remember
var path = require('path');
var myNick = "FruitieX";
var hilight_re = new RegExp(".*" + myNick + ".*", 'i');
var ansi_escape_re = /\x1b[^m]*m/;

var separatorColor = clc.xterm(239);
var numColor = clc.xterm(232).bgXterm(255);
var chanColor = clc.xterm(255).bgXterm(239);
var myNickColor = 1;
var hilightColor = 3;

// we need this in global scope so we can remove the event listeners!
var out;
var openChan = function(filePath) {
	var outFile = filePath + '/out';
	var inFile = filePath + '/in';
	var file = require('fs').readFileSync(outFile, 'utf8');

	var bn = path.basename(filePath);
	var num_s = bn.substring(0, bn.indexOf('_'));
	var num = "";
	if(num_s !== "") {
		num_s = ' ' + num_s + ' ';
		num = numColor(num_s);
	}
	var chan_s = ' ' + bn.substring(bn.indexOf('_') + 1, bn.length) + ' ';
	var chan = chanColor(chan_s);

	var printLine = function(line) {
		var hilight = false;

		// clear channel name
		process.stdout.write('\r' + Array(num_s.length + chan_s.length + 1).join(' ') + '\r');

		// remove timestamps
		line = line.replace(/^([^ ]+ ){2}/, '');
		line = line.split(' ');
		// remove <> around nick
		var nick = line[0].substring(1, line[0].length - 1);

		if(nick === myNick) {
			clrnick = myNickColor;
		} else {
			// nick color, avoids dark colors
			var clrnick = 0;
			for(var i = 0; i < nick.length; i++) {
				clrnick += nick.charCodeAt(i);
			}
			clrnick = Math.pow(clrnick, 2) + clrnick * 2;
			clrnick = clrnick % 255;
			switch(clrnick) {
				case 18: case 22: case 23: case 24:
					clrnick += 3; break;
				case 52: case 53: case 54: case 55: case 56: case 57: case 88: case 89:
					clrnick += 6; break;
				case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239:
					clrnick += 8; break;
				case 0: case 8: case 19: case 22:
					clrnick++; break;
			}
		}

		// limit nicklen
		nick = nick.substr(0, maxNickLen);
		// align nicks
		process.stdout.write(Array(maxNickLen - nick.length + 1).join(' '));
		process.stdout.write(clc.xterm(clrnick)(nick) + separatorColor(':'));
		process.stdout.write(' ');

		// remove nick from line array, now contains space separated text message
		line.shift();
		line = line.join(' ');
		line = line.replace(ansi_escape_re, '');

		if(line.match(hilight_re))
			hilight = true;

		var textColor = 15;
		if (nick === myNick)
			textColor = myNickColor;
		else if (hilight)
			textColor = hilightColor;

		// separator takes up 1 char + whitespace
		var availWidth = process.stdout.columns - maxNickLen - 2;

		var wrappedChars = 0;
		var i = 0;

		while(i * availWidth - wrappedChars < line.length) {
			var start = i * availWidth - wrappedChars;
			var curLine = line.substr(start, availWidth);
			// remove leading space on next line
			curLine.replace(/^\s+/, '');
			// line wrap at word boundary only if there is whitespace on this line
			if(start + availWidth < line.length && curLine.lastIndexOf(' ') !== -1) {
				curLine = curLine.slice(0, curLine.lastIndexOf(' '));
				// remove whitespace
				wrappedChars--;
			}

			wrappedChars += availWidth - curLine.length;

			// empty space on line wrap
			if (i > 0)
				process.stdout.write(Array(process.stdout.columns - availWidth + 1).join(' '));

			process.stdout.write(clc.xterm(textColor)(curLine));
			process.stdout.write('\n');
			i++;
		}

		// print channel name again
		process.stdout.write(num + chan + ' ');
	};

	// log entire file
	var printFile = function(file) {
		var start = 0;
		while (start < file.length) {
			var end = file.indexOf('\n', start);
			if(end === -1)
				break;
			printLine(file.substring(start, end));
			start = end + 1;
		}
	};

	// limit file to size fileBuf
	if(file.length >= fileBuf) {
		file = file.substr(file.length - fileBuf, file.length);
		file = file.substr(file.indexOf("\n") + 1, file.length);
	}

	// set raw mode
	var stdin = process.stdin;
	stdin.setRawMode(true);
	stdin.resume();
	stdin.setEncoding('utf8');

	// handle 'q', 'ctrl-c' by quitting
	stdin.on('data', function(key) {
		if(key == 'q' || key == '\u0003') process.exit();
	});

	// clear terminal and print
	process.stdout.write('\u001B[2J\u001B[0;0f');
	printFile(file);

	// watch file
	Tail = require('tail').Tail;
	out = new Tail(outFile);

	out.on('line', function(data) {
		file += data + '\n';
		// limit file to size fileBuf
		if(file.length >= fileBuf) {
			file = file.substr(file.length - fileBuf, file.length);
			file = file.substr(file.indexOf("\n") + 1, file.length);
		}

		// print the line
		printLine(data);
	});

	process.stdout.on('resize', function() {
		process.stdout.write('\u001B[2J\u001B[0;0f');
		printFile(file);
	});
};

// TODO: changing channels?
var currentChan = process.argv[2];
openChan(process.argv[2]);
<|endoftext|>


<commit_before>import { Component, PropTypes } from "react";
import { connect } from "react-apollo";
import gql from "graphql-tag";

import {
  nav as navActions,
  modal as modalActions,
  give as giveActions,
  header as headerActions,
} from "../../../../store";

import Confirm from "./Confirm";
import Layout from "./Layout";

const mapQueriesToProps = ({ ownProps }) => ({
  entries: {
    query: gql`
      query GetTaggedContent($tagName: String!, $limit: Int, $includeChannels: [String]) {
        entries: taggedContent(tagName: $tagName, limit: $limit, includeChannels: $includeChannels) {
          entryId: id
          title
          channelName
          status
          meta { summary, urlTitle }
          content { images(sizes: ["large"]) { fileName, fileType, fileLabel, url } }
        }
      }
    `,
    variables: {
      tagName: "giving",
      limit: 2,
      includeChannels: ["articles"],
    },
  },
  data: {
    query: gql`
      query GetScheduleTransaction($scheduleTransactionId: ID!) {
        transaction: node(id: $scheduleTransactionId) {
          ... on ScheduledTransaction {
            numberOfPayments
            next
            end
            id: entityId
            reminderDate
            gateway
            start
            date
            details { amount, account { name, description } }
            payment { paymentType, accountNumber, id }
            schedule { value, description }
            transactions {
              id
              date
              status
              summary
              person { firstName, lastName, photo }
              details { id, amount, account { id, name } }
            }
          }
        }
      }
    `,
    variables: { scheduleTransactionId: ownProps.params.id },
    forceFetch: true,
  },
});

@connect({ mapQueriesToProps })
export default class Details extends Component {

  state = {
    isActive: true,
    removed: null,
  }

  componentWillMount() {
    this.props.dispatch(navActions.setLevel("BASIC_CONTENT"));
  }

  componentDidMount(){
    if (process.env.NATIVE) {
      const item = {
        title: "Schedule Details",
      };

      this.props.dispatch(headerActions.set(item));
      this.setState({
        __headerSet: true,
      });
    }

  }

  componentWillUnmount() {
    this.props.dispatch(navActions.setLevel("TOP"));
    if (this.state.removed) {
      this.props.dispatch(giveActions.deleteSchedule(this.state.removed));
    }
  }

  stop = (e) => {
    e.preventDefault();

    this.props.dispatch(modalActions.render(Confirm, {
      onFinished: () => {
        const { id, gateway } = this.props.data.transaction;

        this.setState({isActive: false, removed: id});
        Meteor.call("give/schedule/cancel", { id, gateway }, (err, response) => {
          // eslint-disable-line
        });
      },
    }));
  }

  render() {
    let complete = false;
    let { transaction } = this.props.data;
    transaction || (transaction = false);
    if (new Date(transaction.next) < new Date() && transaction.schedule.value === "One-Time") {
      complete = true;
    }

    const { entries, loading } = this.props.entries;

    return (
      <Layout
        stop={this.stop}
        schedule={transaction}
        ready={!this.props.data.loading}
        state={this.state}
        active={this.state.isActive}
        complete={complete}
        entries={entries}
        loadingEntries={loading}
      />
    );
  }
}
<commit_msg>lint give schedules details index<commit_after>import { Component, PropTypes } from "react";
import { connect } from "react-apollo";
import gql from "graphql-tag";

import {
  nav as navActions,
  modal as modalActions,
  give as giveActions,
  header as headerActions,
} from "../../../../store";

import Confirm from "./Confirm";
import Layout from "./Layout";

const mapQueriesToProps = ({ ownProps }) => ({
  entries: {
    query: gql`
      query GetTaggedContent($tagName: String!, $limit: Int, $includeChannels: [String]) {
        entries: taggedContent(
          tagName: $tagName,
          limit: $limit,
          includeChannels: $includeChannels
        ) {
          entryId: id
          title
          channelName
          status
          meta { summary, urlTitle }
          content { images(sizes: ["large"]) { fileName, fileType, fileLabel, url } }
        }
      }
    `,
    variables: {
      tagName: "giving",
      limit: 2,
      includeChannels: ["articles"],
    },
  },
  data: {
    query: gql`
      query GetScheduleTransaction($scheduleTransactionId: ID!) {
        transaction: node(id: $scheduleTransactionId) {
          ... on ScheduledTransaction {
            numberOfPayments
            next
            end
            id: entityId
            reminderDate
            gateway
            start
            date
            details { amount, account { name, description } }
            payment { paymentType, accountNumber, id }
            schedule { value, description }
            transactions {
              id
              date
              status
              summary
              person { firstName, lastName, photo }
              details { id, amount, account { id, name } }
            }
          }
        }
      }
    `,
    variables: { scheduleTransactionId: ownProps.params.id },
    forceFetch: true,
  },
});

@connect({ mapQueriesToProps })
export default class Details extends Component {

  static propTypes = {
    dispatch: PropTypes.func.isRequired,
    data: {
      transaction: PropTypes.object.isRequired,
    },
    entries: PropTypes.object.isRequired,
  }

  state = {
    isActive: true,
    removed: null,
  }

  componentWillMount() {
    this.props.dispatch(navActions.setLevel("BASIC_CONTENT"));
  }

  componentDidMount(){
    if (process.env.NATIVE) {
      const item = {
        title: "Schedule Details",
      };

      this.props.dispatch(headerActions.set(item));
      this.setState({
        __headerSet: true,
      });
    }

  }

  componentWillUnmount() {
    this.props.dispatch(navActions.setLevel("TOP"));
    if (this.state.removed) {
      this.props.dispatch(giveActions.deleteSchedule(this.state.removed));
    }
  }

  stop = (e) => {
    e.preventDefault();

    this.props.dispatch(modalActions.render(Confirm, {
      onFinished: () => {
        const { id, gateway } = this.props.data.transaction;

        this.setState({ isActive: false, removed: id });
        Meteor.call("give/schedule/cancel", { id, gateway }, () => {
        });
      },
    }));
  }

  render() {
    let complete = false;
    let { transaction } = this.props.data;
    if (!transaction) {
      transaction = false;
    }
    if (new Date(transaction.next) < new Date() && transaction.schedule.value === "One-Time") {
      complete = true;
    }

    const { entries, loading } = this.props.entries;

    return (
      <Layout
        stop={this.stop}
        schedule={transaction}
        ready={!this.props.data.loading}
        state={this.state}
        active={this.state.isActive}
        complete={complete}
        entries={entries}
        loadingEntries={loading}
      />
    );
  }
}
<|endoftext|>


<commit_before>var DbEditor = require('./DbManipulator');
var Schema = require('./Schema');

var getArticle = function(id, callback){
  var q = 'SELECT ' + Schema.Article.column.id + ', ' + Schema.User.column.username + ' as author ,' + Schema.Article.column.content + ', ' + Schema.Article.column.time + ', ' + Schema.Article.column.title + ', ' + Schema.ArticleImage.column.url + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Article.column.id + '=' + id + ' AND ' + Schema.Article.column.authorId + '=' + Schema.User.column.commentId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Article.table, ['*'], [Schema.Article.column.id+'='], [id], callback);
};

var getLatestArticles = function(callback){
  var q = 'SELECT articleId, username as author, content, createTime, title' + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Article.table + '.' + Schema.Article.column.authorId + '=' + Schema.User.table + '.' + Schema.User.column.id + ' ' +
          'ORDER BY ' + Schema.Article.column.time + ' DESC;';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getLove = function(articleId, callback){
  var q = 'SELECT ' + Schema.Love.column.uid + ', '+ Schema.User.column.fname + ', ' + Schema.User.column.lname + ' ' +
          'FROM ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Love.table + '.' + Schema.Love.column.aid + '=' + articleId + ' AND ' + Schema.Article.table + '.' + Schema.Love.column.uid + '=' + Schema.User.table +'.' + Schema.User.column.id +';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Love.table, [Schema.Love.column.uid, 'count(' + Schema.Love.column.aid +') as number'], [Schema.Love.column.aid+'='], [articleId], callback);
};

var postLove = function(userId, articleId, callback){
  var q = 'INSERT INTO ' + Schema.Love.table + ' VALUES (' + articleId + ', ' + userId + ');';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var deleteLove = function(userId, articleId, callback){
  var q = 'DELETE FROM ' + Schema.Love.table +
          ' WHERE ' + Schema.Love.column.uid + '=' + userId + ' AND ' + Schema.Love.column.aid + '=' + articleId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postArticle = function(newArticleId ,userId, title, content, callback){
  var q = 'INSERT INTO ' + Schema.Article.table +
          ' VALUES ('+ newArticleId + ', ' + userId + ', ' + title + ', ' + content + ', NOW() );';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getComments = function(articleId, callback){
  var q = 'SELECT ' + Schema.Comment.column.commentId + ', ' + Schema.User.column.fname + ', ' + Schema.User.column.lname + ', ' + Schema.Comment.column.comment + ', ' + Schema.Comment.column.time + ' ' +
          'FROM ' + Schema.Comment.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Comment.column.aid + '=' + articleId + ' AND ' + Schema.Comment.column.commentorId + '=' + Schema.User.column.id + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Comment.table, [Schema.Comment.column.commentId, Schema.Comment.column.commentorId, Schema.Comment.column.comment, 'date_format(' + Schema.Comment.column.time + ', \'%e-%c-%Y %T\') as createTime'], [Schema.Comment.column.aid+'='], [articleId], callback);
};

var postComment = function(newCommentId, articleId, commentorId, comment, callback){
  var q = 'INSERT INTO ' + Schema.Comment.table + ' ' +
          'VALUES (' + newCommentId + ', ' + articleId + ', ' + commentorId + ', ' + toString(comment) + ', NOW());';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getTagInArticle = function(articleId, callback){
  var q = 'SELECT ' + Schema.Tag.column.tagName + ' ' +
          'FROM ' + Schema.Tag.table + ' ' +
          'WHERE ' + Schema.Tag.column.articleId + '=' + articleId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Tag.table, [Schema.Tag.column.tagName], [Schema.Tag.column.articleId+'='], articleId, callback);
};

var getTaggedArticles = function(tagName, callback){
  var q = 'SELECT ' + Schema.Article.column.id + ', ' + Schema.Article.column.title + ', ' + Schema.Article.column.content + ', ' + Schema.Article.column.time + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.Tag.table + ' ' +
          'WHERE ' + Schema.Tag.column.tagName + '=' + tagName + ' AND ' + Schema.Tag.column.articleId + '=' + Schema.Article.column.id + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getUserInfo = function(username, callback){
  var q = 'SELECT ' + Schema.User.column.id + ', ' + Schema.User.column.username + ', ' + Schema.User.column.fname + ', ' + Schema.User.column.lname + ' ' +
          'FROM ' + Schema.User.table + ' '+
          'WHERE ' + Schema.User.column.username + '=' + toString(username) + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postArticleImage = function(articleId, imageURL, callback){
  var q = 'INSERT INTO ' + Schema.ArticleImage.table + ' ' +
          'VAULES (' + articleId + ', ' + toString(imageURL) + ');';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postTagFromArticle = function(articleId, tags, callback){
  var q = 'INSERT INTO ' + Schema.Tag.table + ' ' +
          'VALUES ';
  for(var i = 0; i < tags.length; i++) {
    q += '( ' + toString(tags[i]) + ', ' + articleId + ')';
    if(i < tags.length - 1) q += ',';
    else q += ';';
  }
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

function toString(s){
  return '\''+s+'\'';
}

module.exports = {
  getArticle: getArticle,
  getLatestArticle: getLatestArticles,
  getLovesInArticle: getLove,
  postLoveToArticle: postLove,
  removeLoveFromArticle: deleteLove,
  postArticle: postArticle,
  getCommentsOfArticle: getComments,
  postCommentsToArticle: postComment,
  getTagInArticle: getTagInArticle,
  getTaggedArticles: getTaggedArticles,
  getUserInfo: getUserInfo
};
<commit_msg>fix missing table in getLove<commit_after>var DbEditor = require('./DbManipulator');
var Schema = require('./Schema');

var getArticle = function(id, callback){
  var q = 'SELECT ' + Schema.Article.column.id + ', ' + Schema.User.column.username + ' as author ,' + Schema.Article.column.content + ', ' + Schema.Article.column.time + ', ' + Schema.Article.column.title + ', ' + Schema.ArticleImage.column.url + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Article.column.id + '=' + id + ' AND ' + Schema.Article.column.authorId + '=' + Schema.User.column.commentId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Article.table, ['*'], [Schema.Article.column.id+'='], [id], callback);
};

var getLatestArticles = function(callback){
  var q = 'SELECT articleId, username as author, content, createTime, title' + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Article.table + '.' + Schema.Article.column.authorId + '=' + Schema.User.table + '.' + Schema.User.column.id + ' ' +
          'ORDER BY ' + Schema.Article.column.time + ' DESC;';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getLove = function(articleId, callback){
  var q = 'SELECT ' + Schema.Love.column.uid + ', '+ Schema.User.column.fname + ', ' + Schema.User.column.lname + ' ' +
          'FROM ' + Schema.User.table + ', ' + Schema.Love.table + ' ' +
          'WHERE ' + Schema.Love.table + '.' + Schema.Love.column.aid + '=' + articleId + ' AND ' + Schema.Article.table + '.' + Schema.Love.column.uid + '=' + Schema.User.table +'.' + Schema.User.column.id +';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Love.table, [Schema.Love.column.uid, 'count(' + Schema.Love.column.aid +') as number'], [Schema.Love.column.aid+'='], [articleId], callback);
};

var postLove = function(userId, articleId, callback){
  var q = 'INSERT INTO ' + Schema.Love.table + ' VALUES (' + articleId + ', ' + userId + ');';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var deleteLove = function(userId, articleId, callback){
  var q = 'DELETE FROM ' + Schema.Love.table +
          ' WHERE ' + Schema.Love.column.uid + '=' + userId + ' AND ' + Schema.Love.column.aid + '=' + articleId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postArticle = function(newArticleId ,userId, title, content, callback){
  var q = 'INSERT INTO ' + Schema.Article.table +
          ' VALUES ('+ newArticleId + ', ' + userId + ', ' + title + ', ' + content + ', NOW() );';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getComments = function(articleId, callback){
  var q = 'SELECT ' + Schema.Comment.column.commentId + ', ' + Schema.User.column.fname + ', ' + Schema.User.column.lname + ', ' + Schema.Comment.column.comment + ', ' + Schema.Comment.column.time + ' ' +
          'FROM ' + Schema.Comment.table + ', ' + Schema.User.table + ' ' +
          'WHERE ' + Schema.Comment.column.aid + '=' + articleId + ' AND ' + Schema.Comment.column.commentorId + '=' + Schema.User.column.id + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Comment.table, [Schema.Comment.column.commentId, Schema.Comment.column.commentorId, Schema.Comment.column.comment, 'date_format(' + Schema.Comment.column.time + ', \'%e-%c-%Y %T\') as createTime'], [Schema.Comment.column.aid+'='], [articleId], callback);
};

var postComment = function(newCommentId, articleId, commentorId, comment, callback){
  var q = 'INSERT INTO ' + Schema.Comment.table + ' ' +
          'VALUES (' + newCommentId + ', ' + articleId + ', ' + commentorId + ', ' + toString(comment) + ', NOW());';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getTagInArticle = function(articleId, callback){
  var q = 'SELECT ' + Schema.Tag.column.tagName + ' ' +
          'FROM ' + Schema.Tag.table + ' ' +
          'WHERE ' + Schema.Tag.column.articleId + '=' + articleId + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
  // DbEditor.query(Schema.Tag.table, [Schema.Tag.column.tagName], [Schema.Tag.column.articleId+'='], articleId, callback);
};

var getTaggedArticles = function(tagName, callback){
  var q = 'SELECT ' + Schema.Article.column.id + ', ' + Schema.Article.column.title + ', ' + Schema.Article.column.content + ', ' + Schema.Article.column.time + ' ' +
          'FROM ' + Schema.Article.table + ', ' + Schema.Tag.table + ' ' +
          'WHERE ' + Schema.Tag.column.tagName + '=' + tagName + ' AND ' + Schema.Tag.column.articleId + '=' + Schema.Article.column.id + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var getUserInfo = function(username, callback){
  var q = 'SELECT ' + Schema.User.column.id + ', ' + Schema.User.column.username + ', ' + Schema.User.column.fname + ', ' + Schema.User.column.lname + ' ' +
          'FROM ' + Schema.User.table + ' '+
          'WHERE ' + Schema.User.column.username + '=' + toString(username) + ';';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postArticleImage = function(articleId, imageURL, callback){
  var q = 'INSERT INTO ' + Schema.ArticleImage.table + ' ' +
          'VAULES (' + articleId + ', ' + toString(imageURL) + ');';
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

var postTagFromArticle = function(articleId, tags, callback){
  var q = 'INSERT INTO ' + Schema.Tag.table + ' ' +
          'VALUES ';
  for(var i = 0; i < tags.length; i++) {
    q += '( ' + toString(tags[i]) + ', ' + articleId + ')';
    if(i < tags.length - 1) q += ',';
    else q += ';';
  }
  console.log(q);
  DbEditor.rawQuery(q, callback);
};

function toString(s){
  return '\''+s+'\'';
}

module.exports = {
  getArticle: getArticle,
  getLatestArticle: getLatestArticles,
  getLovesInArticle: getLove,
  postLoveToArticle: postLove,
  removeLoveFromArticle: deleteLove,
  postArticle: postArticle,
  getCommentsOfArticle: getComments,
  postCommentsToArticle: postComment,
  getTagInArticle: getTagInArticle,
  getTaggedArticles: getTaggedArticles,
  getUserInfo: getUserInfo
};
<|endoftext|>