<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Called by the common.js module.
function domContentLoaded(name, tc, config, width, height) {
  var listener = document.getElementById('listener');
  listener.addEventListener('loadstart', moduleDidStartLoad, true);
  listener.addEventListener('progress', moduleLoadProgress, true);
  listener.addEventListener('error', moduleLoadError, true);
  listener.addEventListener('abort', moduleLoadAbort, true);
  listener.addEventListener('load', moduleDidLoad, true);
  listener.addEventListener('loadend', moduleDidEndLoad, true);
  listener.addEventListener('message', handleMessage, true);

  common.createNaClModule(name, tc, config, width, height);
}

// Handler that gets called when the NaCl module starts loading.  This
// event is always triggered when an <EMBED> tag has a MIME type of
// application/x-nacl.
function moduleDidStartLoad() {
  common.logMessage('loadstart');
}

// Progress event handler.  |event| contains a couple of interesting
// properties that are used in this example:
//     total The size of the NaCl module in bytes.  Note that this value
//         is 0 until |lengthComputable| is true.  In particular, this
//         value is 0 for the first 'progress' event.
//     loaded The number of bytes loaded so far.
//     lengthComputable A boolean indicating that the |total| field
//         represents a valid length.
//
// event The ProgressEvent that triggered this handler.
function moduleLoadProgress(event) {
  var loadPercent = 0.0;
  var loadPercentString;
  if (event.lengthComputable && event.total > 0) {
    loadPercent = event.loaded / event.total * 100.0;
    loadPercentString = loadPercent + '%';
  } else {
    // The total length is not yet known.
    loadPercent = -1.0;
    loadPercentString = 'Computing...';
  }
  common.logMessage('progress: ' + loadPercentString +
                   ' (' + event.loaded + ' of ' + event.total + ' bytes)');
}

// Handler that gets called if an error occurred while loading the NaCl
// module.  Note that the event does not carry any meaningful data about
// the error, you have to check lastError on the <EMBED> element to find
// out what happened.
function moduleLoadError() {
  common.logMessage('error: ' + common.naclModule.lastError);
}

// Handler that gets called if the NaCl module load is aborted.
function moduleLoadAbort() {
  common.logMessage('abort');
}

// When the NaCl module has loaded indicate success.
function moduleDidLoad() {
  common.logMessage('load');
  common.updateStatus('LOADED');
}

// Handler that gets called when the NaCl module loading has completed.
// You will always get one of these events, regardless of whether the NaCl
// module loaded successfully or not.  For example, if there is an error
// during load, you will get an 'error' event and a 'loadend' event.  Note
// that if the NaCl module loads successfully, you will get both a 'load'
// event and a 'loadend' event.
function moduleDidEndLoad() {
  common.logMessage('loadend');
  var lastError = event.target.lastError;
  if (lastError == undefined || lastError.length == 0) {
    lastError = '<none>';
  }
  common.logMessage('lastError: ' + lastError);
}

// Handle a message coming from the NaCl module.
function handleMessage(message_event) {
  common.logMessage('Received PostMessage: ' + message_event.data);
}
<commit_msg>[NaCl SDK] Add URL to load progress tutorial<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Called by the common.js module.
function domContentLoaded(name, tc, config, width, height) {
  var listener = document.getElementById('listener');
  listener.addEventListener('loadstart', moduleDidStartLoad, true);
  listener.addEventListener('progress', moduleLoadProgress, true);
  listener.addEventListener('error', moduleLoadError, true);
  listener.addEventListener('abort', moduleLoadAbort, true);
  listener.addEventListener('load', moduleDidLoad, true);
  listener.addEventListener('loadend', moduleDidEndLoad, true);
  listener.addEventListener('message', handleMessage, true);

  common.createNaClModule(name, tc, config, width, height);
}

// Handler that gets called when the NaCl module starts loading.  This
// event is always triggered when an <EMBED> tag has a MIME type of
// application/x-nacl.
function moduleDidStartLoad() {
  common.logMessage('loadstart');
}

// Progress event handler.  |event| contains a couple of interesting
// properties that are used in this example:
//     total The size of the NaCl module in bytes.  Note that this value
//         is 0 until |lengthComputable| is true.  In particular, this
//         value is 0 for the first 'progress' event.
//     loaded The number of bytes loaded so far.
//     lengthComputable A boolean indicating that the |total| field
//         represents a valid length.
//
// event The ProgressEvent that triggered this handler.
function moduleLoadProgress(event) {
  var loadPercent = 0.0;
  var loadPercentString;
  if (event.lengthComputable && event.total > 0) {
    loadPercent = event.loaded / event.total * 100.0;
    loadPercentString = loadPercent + '%';
    common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
                     ' (' + event.loaded + ' of ' + event.total + ' bytes)');
  } else {
    // The total length is not yet known.
    common.logMessage('progress: Computing...');
  }
}

// Handler that gets called if an error occurred while loading the NaCl
// module.  Note that the event does not carry any meaningful data about
// the error, you have to check lastError on the <EMBED> element to find
// out what happened.
function moduleLoadError() {
  common.logMessage('error: ' + common.naclModule.lastError);
}

// Handler that gets called if the NaCl module load is aborted.
function moduleLoadAbort() {
  common.logMessage('abort');
}

// When the NaCl module has loaded indicate success.
function moduleDidLoad() {
  common.logMessage('load');
  common.updateStatus('LOADED');
}

// Handler that gets called when the NaCl module loading has completed.
// You will always get one of these events, regardless of whether the NaCl
// module loaded successfully or not.  For example, if there is an error
// during load, you will get an 'error' event and a 'loadend' event.  Note
// that if the NaCl module loads successfully, you will get both a 'load'
// event and a 'loadend' event.
function moduleDidEndLoad() {
  common.logMessage('loadend');
  var lastError = event.target.lastError;
  if (lastError == undefined || lastError.length == 0) {
    lastError = '<none>';
  }
  common.logMessage('lastError: ' + lastError);
}

// Handle a message coming from the NaCl module.
function handleMessage(message_event) {
  common.logMessage('Received PostMessage: ' + message_event.data);
}
<|endoftext|>


<commit_before>var ArgumentError = require('rest-facade').ArgumentError;
var Auth0RestClient = require('../Auth0RestClient');
var RetryRestClient = require('../RetryRestClient');

/**
 * @class
 * Abstracts interaction with the migrations endpoint.
 * @constructor
 * @memberOf module:management
 *
 * @param {Object} options            The client options.
 * @param {String} options.baseUrl    The URL of the API.
 * @param {Object} [options.headers]  Headers to be included in all requests.
 * @param {Object} [options.retry]    Retry Policy Config
 */
var MigrationsManager = function(options) {
  if (options === null || typeof options !== 'object') {
    throw new ArgumentError('Must provide manager options');
  }

  if (options.baseUrl === null || options.baseUrl === undefined) {
    throw new ArgumentError('Must provide a base URL for the API');
  }

  if ('string' !== typeof options.baseUrl || options.baseUrl.length === 0) {
    throw new ArgumentError('The provided base URL is invalid');
  }

  var clientOptions = {
    errorFormatter: { message: 'message', name: 'error' },
    headers: options.headers,
    query: { repeatParams: false }
  };

  /**
   * Provides an abstraction layer for consuming the migrations endpoint
   *
   * @type {external:RestClient}
   */
  var auth0RestClient = new Auth0RestClient(
    options.baseUrl + '/migrations',
    clientOptions,
    options.tokenProvider
  );
  this.resource = new RetryRestClient(auth0RestClient, options.retry);
};

/**
 * Update the tenant migrations.
 *
 * @method    updateMigrations
 * @memberOf  module:management.MigrationsManager.prototype
 *
 * @example
 * management.migrations.updateMigrations(data, function (err) {
 *   if (err) {
 *     // Handle error.
 *   }
 * });
 *
 * @param   {Object}    data  The tenant migrations to be updated
 * @param   {Object}    data.flags  The tenant migrations flags to be updated
 * @param   {Function}  [cb]  Callback function.
 *
 * @return  {Promise|undefined}
 */
MigrationsManager.prototype.updateMigrations = function(data, cb) {
  if (cb && cb instanceof Function) {
    return this.resource.patch({}, data, cb);
  }

  // Return a promise.
  return this.resource.patch({}, data);
};

/**
 * Get the tenant migrations.
 *
 * @method    getMigrations
 * @memberOf  module:management.MigrationsManager.prototype
 *
 * @example
 * management.migrations.getMigrations(function (err, settings) {
 *   if (err) {
 *     // Handle error.
 *   }
 *
 *   console.log(settings);
 * });
 *
 * @param   {Function}  [cb]    Callback function.
 *
 * @return  {Promise|undefined}
 */
MigrationsManager.prototype.getMigrations = function(data, cb) {
  if (data instanceof Function && !cb) {
    cb = data;
    data = {};
  }
  if (cb && cb instanceof Function) {
    return this.resource.get(data, cb);
  }

  // Return a promise.
  return this.resource.get(data);
};

module.exports = MigrationsManager;
<commit_msg>Update src/management/MigrationsManager.js<commit_after>var ArgumentError = require('rest-facade').ArgumentError;
var Auth0RestClient = require('../Auth0RestClient');
var RetryRestClient = require('../RetryRestClient');

/**
 * @class
 * Abstracts interaction with the migrations endpoint.
 * @constructor
 * @memberOf module:management
 *
 * @param {Object} options            The client options.
 * @param {String} options.baseUrl    The URL of the API.
 * @param {Object} [options.headers]  Headers to be included in all requests.
 * @param {Object} [options.retry]    Retry Policy Config
 */
var MigrationsManager = function(options) {
  if (options === null || typeof options !== 'object') {
    throw new ArgumentError('Must provide manager options');
  }

  if (options.baseUrl === null || options.baseUrl === undefined) {
    throw new ArgumentError('Must provide a base URL for the API');
  }

  if ('string' !== typeof options.baseUrl || options.baseUrl.length === 0) {
    throw new ArgumentError('The provided base URL is invalid');
  }

  var clientOptions = {
    errorFormatter: { message: 'message', name: 'error' },
    headers: options.headers,
    query: { repeatParams: false }
  };

  /**
   * Provides an abstraction layer for consuming the migrations endpoint
   *
   * @type {external:RestClient}
   */
  var auth0RestClient = new Auth0RestClient(
    options.baseUrl + '/migrations',
    clientOptions,
    options.tokenProvider
  );
  this.resource = new RetryRestClient(auth0RestClient, options.retry);
};

/**
 * Update the tenant migrations.
 *
 * @method    updateMigrations
 * @memberOf  module:management.MigrationsManager.prototype
 *
 * @example
 * management.migrations.updateMigrations(data, function (err) {
 *   if (err) {
 *     // Handle error.
 *   }
 * });
 *
 * @param   {Object}    data  The tenant migrations to be updated
 * @param   {Object}    data.flags  The tenant migrations flags to be updated
 * @param   {Function}  [cb]  Callback function.
 *
 * @return  {Promise|undefined}
 */
MigrationsManager.prototype.updateMigrations = function(data, cb) {
  if (cb && cb instanceof Function) {
    return this.resource.patch({}, data, cb);
  }

  // Return a promise.
  return this.resource.patch({}, data);
};

/**
 * Get the tenant migrations.
 *
 * @method    getMigrations
 * @memberOf  module:management.MigrationsManager.prototype
 *
 * @example
 * management.migrations.getMigrations(function (err, migrations) {
 *   if (err) {
 *     // Handle error.
 *   }
 *
 *   console.log(migrations.flags);
 * });
 *
 * @param   {Function}  [cb]    Callback function.
 *
 * @return  {Promise|undefined}
 */
MigrationsManager.prototype.getMigrations = function(data, cb) {
  if (data instanceof Function && !cb) {
    cb = data;
    data = {};
  }
  if (cb && cb instanceof Function) {
    return this.resource.get(data, cb);
  }

  // Return a promise.
  return this.resource.get(data);
};

module.exports = MigrationsManager;
<|endoftext|>


<commit_before>'use strict';

// external deps
var ObjectId = require('mongodb').ObjectId;

// internal deps
require('mongodb-toolkit');
var BaseManager = require('module-toolkit').BaseManager;
var ComponentHelper = require('./component-helper');

var BateeqModels = require('bateeq-models');
var Item = BateeqModels.master.Item;
var FinishedGoods = BateeqModels.master.FinishedGoods;
var Material = BateeqModels.master.Material;
var map = BateeqModels.map;

module.exports = class ItemManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.Item);
        this.componentHelper = new ComponentHelper(this);
    }

    upsertComponents(data) {
        return new Promise((resolve, reject) => {
            var tag = `#${data.code}`;
            var task = [];
            for (var component of data.components) {

                var item = component.item;
                var tags = (item.tags || '').split(",").filter(el => el && el.trim().length > 0);
                var tagIndex = tags.findIndex(t => {
                    return t == tag;
                });

                if (tagIndex < 0)
                    tags.push(tag);

                item.tags = tags.join(",");

                if (item._id)
                    task.push(this.update(item));
                else
                    task.push(this.create(item));
            }

            Promise.all(task)
                .then(results => {
                    var getItems = [];

                    for (var itemId of results)
                        getItems.push(this.getSingleById(itemId));

                    Promise.all(getItems)
                        .then(items => {
                            var index = 0;
                            for (var item of items) {
                                var component = data.components[index++];
                                component.itemId = item._id;
                                component.item = item;
                            }
                            this.collection.update(data).then(id => {
                                resolve(id);
                            });
                        })
                        .catch(e => {
                            reject(e);
                        });
                })
                .catch(e => {
                    reject(e);
                });

        });
    }

    create(data) {
        return new Promise((resolve, reject) => {
            this._validate(data)
                .then(validData => {
                    this.collection.insert(validData)
                        .then(id => {
                            validData._id = id;
                            this.upsertComponents(validData)
                                .then(id => {
                                    resolve(id);
                                })
                                .catch(e => {
                                    reject(e);
                                });
                        })
                        .catch(e => {
                            reject(e);
                        });
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    update(data) {
        return new Promise((resolve, reject) => {
            this._validate(data)
                .then(validData => {
                    this.collection.update(validData)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    getByCode(code) {
        return new Promise((resolve, reject) => {
            if (code === '')
                resolve(null);
            var query = {
                code: code,
                _deleted: false
            };
            this.collection.singleOrDefault(query)
                .then(item => {
                    resolve(item);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    _getQuery(paging) {
        var basicFilter = {
            _deleted: false
        }, keywordFilter = {};

        var query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var filterCode = {
                'code': {
                    '$regex': regex
                }
            };
            var filterName = {
                'name': {
                    '$regex': regex
                }
            };

            keywordFilter = {
                '$or': [filterCode, filterName]
            };
        }
        query = { '$and': [basicFilter, paging.filter, keywordFilter] };
        return query;
    }

    _validate(data) {
        var errors = {};
        return new Promise((resolve, reject) => {
            // 1. begin: Declare promises.
            var getItem = this.collection.singleOrDefault({
                "$and": [{
                    _id: {
                        '$ne': new ObjectId(data._id)
                    }
                }, {
                    code: data.code
                }]
            });
            // 1. end: Declare promises.

            // 2. begin: Validation.
            Promise.all([getItem])
                .then(results => {
                    var _item = results[0];

                    if (!data.code || data.code == '')
                        errors["code"] = "code is required";
                    else if (_item)
                        errors["code"] = "code already exists";

                    if (!data.name || data.name == '')
                        errors["name"] = "name is required";

                    if (!data.uom || data.uom == '')
                        errors["uom"] = "uom is required";

                    this.componentHelper.validate(data.components)
                        .then(result => {
                            data.components = result.components;

                            // 2c. begin: check if data has any error, reject if it has.
                            for (var prop in errors) {
                                var ValidationError = require('module-toolkit').ValidationError;
                                reject(new ValidationError('data does not pass validation', errors));
                            }
                            var valid = data;
                            if (!valid.stamp) {
                                switch (data._type) {
                                    case 'material':
                                        valid = new Material(data);
                                        break;
                                    case 'finished-goods':
                                        valid = new FinishedGoods(data);
                                        break;
                                    default:
                                        valid = new Item(data);
                                }
                            }
                            valid.stamp(this.user.username, 'manager');
                            resolve(valid);
                        })
                        .catch(e => {
                            errors["components"] = e;

                            // 2c. begin: check if data has any error, reject if it has.
                            for (var prop in errors) {
                                var ValidationError = require('module-toolkit').ValidationError;
                                reject(new ValidationError('data does not pass validation', errors));
                            }
                        });
                })
                .catch(e => {
                    reject(e);
                })
        });
    }
};<commit_msg>update produk master<commit_after>'use strict';

// external deps
var ObjectId = require('mongodb').ObjectId;

// internal deps
require('mongodb-toolkit');
var BaseManager = require('module-toolkit').BaseManager;
var ComponentHelper = require('./component-helper');

var BateeqModels = require('bateeq-models');
var Item = BateeqModels.master.Item;
var FinishedGoods = BateeqModels.master.FinishedGoods;
var Material = BateeqModels.master.Material;
var Sales = BateeqModels.sales.Sales;
var map = BateeqModels.map;

module.exports = class ItemManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.Item);
        this.salesCollection = this.db.use(map.sales.SalesDoc);
        this.salesReturnCollection = this.db.use(map.sales.SalesReturnDoc);
        this.componentHelper = new ComponentHelper(this);
    }

    upsertComponents(data) {
        return new Promise((resolve, reject) => {
            var tag = `#${data.code}`;
            var task = [];
            for (var component of data.components) {

                var item = component.item;
                var tags = (item.tags || '').split(",").filter(el => el && el.trim().length > 0);
                var tagIndex = tags.findIndex(t => {
                    return t == tag;
                });

                if (tagIndex < 0)
                    tags.push(tag);

                item.tags = tags.join(",");

                if (item._id)
                    task.push(this.update(item));
                else
                    task.push(this.create(item));
            }

            Promise.all(task)
                .then(results => {
                    var getItems = [];

                    for (var itemId of results)
                        getItems.push(this.getSingleById(itemId));

                    Promise.all(getItems)
                        .then(items => {
                            var index = 0;
                            for (var item of items) {
                                var component = data.components[index++];
                                component.itemId = item._id;
                                component.item = item;
                            }
                            this.collection.update(data).then(id => {
                                resolve(id);
                            });
                        })
                        .catch(e => {
                            reject(e);
                        });
                })
                .catch(e => {
                    reject(e);
                });

        });
    }

    create(data) {
        return new Promise((resolve, reject) => {
            this._validate(data)
                .then(validData => {
                    this.collection.insert(validData)
                        .then(id => {
                            validData._id = id;
                            this.upsertComponents(validData)
                                .then(id => {
                                    resolve(id);
                                })
                                .catch(e => {
                                    reject(e);
                                });
                        })
                        .catch(e => {
                            reject(e);
                        });
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    //update 15-6-2017
    update(data) {
        return new Promise((resolve, reject) => {
            this._validate(data)
                .then(validData => {
                    this.collection.update(validData)
                        .then(id => {
                            this.updateItemOnSalesDoc(validData)
                                .then(salesDocUpdate => {
                                    this.updateItemOnSalesReturnDoc(validData)
                                        .then(salesReturnUpDate => {
                                            resolve(id);
                                        })
                                        .catch(e => {
                                            reject(e);
                                        })
                                })
                                .catch(e => {
                                    reject(e);
                                })
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    getByCode(code) {
        return new Promise((resolve, reject) => {
            if (code === '')
                resolve(null);
            var query = {
                code: code,
                _deleted: false
            };
            this.collection.singleOrDefault(query)
                .then(item => {
                    resolve(item);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    _getQuery(paging) {
        var basicFilter = {
            _deleted: false
        }, keywordFilter = {};

        var query = {};

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
            var filterCode = {
                'code': {
                    '$regex': regex
                }
            };
            var filterName = {
                'name': {
                    '$regex': regex
                }
            };

            keywordFilter = {
                '$or': [filterCode, filterName]
            };
        }
        query = { '$and': [basicFilter, paging.filter, keywordFilter] };
        return query;
    }

    _validate(data) {
        var errors = {};
        return new Promise((resolve, reject) => {
            // 1. begin: Declare promises.
            var getItem = this.collection.singleOrDefault({
                "$and": [{
                    _id: {
                        '$ne': new ObjectId(data._id)
                    }
                }, {
                    code: data.code
                }]
            });
            // 1. end: Declare promises.

            // 2. begin: Validation.
            Promise.all([getItem])
                .then(results => {
                    var _item = results[0];

                    if (!data.code || data.code == '')
                        errors["code"] = "code is required";
                    else if (_item)
                        errors["code"] = "code already exists";

                    if (!data.name || data.name == '')
                        errors["name"] = "name is required";

                    if (!data.uom || data.uom == '')
                        errors["uom"] = "uom is required";

                    this.componentHelper.validate(data.components)
                        .then(result => {
                            data.components = result.components;

                            // 2c. begin: check if data has any error, reject if it has.
                            for (var prop in errors) {
                                var ValidationError = require('module-toolkit').ValidationError;
                                reject(new ValidationError('data does not pass validation', errors));
                            }
                            var valid = data;
                            if (!valid.stamp) {
                                switch (data._type) {
                                    case 'material':
                                        valid = new Material(data);
                                        break;
                                    case 'finished-goods':
                                        valid = new FinishedGoods(data);
                                        break;
                                    default:
                                        valid = new Item(data);
                                }
                            }
                            valid.stamp(this.user.username, 'manager');
                            resolve(valid);
                        })
                        .catch(e => {
                            errors["components"] = e;

                            // 2c. begin: check if data has any error, reject if it has.
                            for (var prop in errors) {
                                var ValidationError = require('module-toolkit').ValidationError;
                                reject(new ValidationError('data does not pass validation', errors));
                            }
                        });
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    //15-6-2017
    updateItemOnSalesDoc(data) {
        var filter = {
            'items.item.code': data.code,
            'isVoid': false
        };

        return new Promise((resolve, reject) => {
            this.salesCollection.where(filter).execute()
                .then(salesDocs => {

                    if (salesDocs.data.length > 0) {
                        for (var salesDoc of salesDocs.data) {

                            for (var items of salesDoc.items) {
                                if (items.item.code === data.code) {
                                    items.item = data;
                                }
                            }
                            salesDoc._updatedDate = data._updatedDate;
                            this.salesCollection.update(salesDoc)
                                .then(id => {
                                    resolve();
                                })
                                .catch(e => {
                                    reject(e);
                                })
                        }
                    } else {
                        resolve();
                    }

                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    //stil 15-6-2017
    updateItemOnSalesReturnDoc(data) {
        var query = {};

        var filter = {
            'isVoid': false
        };

        var filterSales = {
            'salesDoc.items.item.code': data.code
        };

        var filterSalesReturn = {
            'salesDocReturn.items.item.code': data.code
        };

        var itemFilter = {
            '$or': [filterSales, filterSalesReturn]
        }

        query = { '$and': [filter, itemFilter] };

        return new Promise((resolve, reject) => [
            this.salesReturnCollection.where(query).execute()
                .then(salesReturnDocs => {

                    if (salesReturnDocs.data.length > 0) {
                        for (var salesReturnDoc of salesReturnDocs.data) {

                            for (var items of salesReturnDoc.salesDoc.items) {
                                if (items.item.code === data.code) {
                                    items.item = data;
                                }
                            }

                            for (var items of salesReturnDoc.salesDocReturn.items) {
                                if (items.item.code === data.code) {
                                    items.item = data;
                                }
                            }

                            salesReturnDoc._updatedDate = data._updatedDate;
                            this.salesReturnCollection.update(salesReturnDoc)
                                .then(id => {
                                    resolve();
                                })
                                .catch(e => {
                                    reject(e);
                                })
                        }
                    } else {
                        resolve();
                    }
                })
                .catch(e => {
                    reject(e);
                })
        ]);
    }
};<|endoftext|>


<commit_before>/* eslint-disable react/no-unused-prop-types */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { View, ToastAndroid } from 'react-native';
import { connect } from 'react-redux';

import { MODAL_KEYS } from '../utilities';
import { DataTablePageModal } from '../widgets/modals';
import { BottomConfirmModal } from '../widgets/bottomModals';
import { DataTable, DataTableHeaderRow, DataTableRow } from '../widgets/DataTable';
import { DATA_TABLE_DEFAULTS } from '../widgets/DataTable/constants';
import {
  DataTablePageView,
  DropDown,
  PageButton,
  PageInfo,
  ToggleBar,
  SearchBar,
} from '../widgets';

import {
  selectIndicatorCodes,
  selectCurrentIndicatorCode,
  selectIndicatorTableColumns,
  selectIndicatorTableRows,
} from '../selectors/indicatorSelectors';
import { getItemLayout, getPageDispatchers, PageActions } from './dataTableUtilities';

import { ROUTES } from '../navigation/constants';

import { useRecordListener } from '../hooks';

import globalStyles from '../globalStyles';
import { buttonStrings, modalStrings, programStrings, generalStrings } from '../localization';
import { UIDatabase } from '../database/index';
import { SETTINGS_KEYS } from '../settings/index';

/**
 * Renders a mSupply mobile page with a supplier requisition loaded for editing
 *
 * State:
 * Uses a reducer to manage state with `backingData` being a realm results
 * of items to display. `data` is a plain JS array of realm objects. data is
 * hydrated from the `backingData` for displaying in the interface.
 * i.e: When filtering, data is populated from filtered items of `backingData`.
 *
 * dataState is a simple map of objects corresponding to a row being displayed,
 * holding the state of a given row. Each object has the shape :
 * { isSelected, isDisabled },
 */
const SupplierRequisition = ({
  runWithLoadingIndicator,
  dispatch,
  data,
  dataState,
  sortKey,
  modalValue,
  isAscending,
  modalKey,
  pageObject,
  hasSelection,
  showAll,
  usingIndicators,
  showIndicators,
  currentIndicatorCode,
  indicatorCodes,
  keyExtractor,
  searchTerm,
  columns,
  getPageInfoColumns,
  refreshData,
  onSelectNewItem,
  onEditComment,
  onFilterData,
  onDeleteItems,
  onDeselectAll,
  onCloseModal,
  onCheck,
  onUncheck,
  onSortColumn,
  onToggleIndicators,
  onSelectIndicator,
  onEditIndicatorValue,
  onShowOverStocked,
  onHideOverStocked,
  onEditMonth,
  onEditRequiredQuantity,
  onAddRequisitionItem,
  onSetRequestedToSuggested,
  onAddMasterList,
  onApplyMasterLists,
  route,
}) => {
  // Listen for changes to this pages requisition. Refreshing data on side effects i.e. finalizing.
  useRecordListener(() => dispatch(refreshData), pageObject, 'Requisition');

  const { isFinalised, comment, theirRef, program, daysToSupply } = pageObject;

  const createAutomaticOrder = () => dispatch(PageActions.createAutomaticOrder(route));
  const onCreateAutomaticOrder = () => runWithLoadingIndicator(createAutomaticOrder);

  const pageInfoColumns = useMemo(() => getPageInfoColumns(pageObject, dispatch, route), [
    comment,
    theirRef,
    isFinalised,
    daysToSupply,
  ]);

  const getCallback = (colKey, propName) => {
    switch (colKey) {
      case 'requiredQuantity':
        return onEditRequiredQuantity;
      case 'remove':
        if (propName === 'onCheck') return onCheck;
        return onUncheck;
      default:
        // Indicators functionality generates columns at run-time from indicator attribute
        // data. If known column key not found, assume column is a dynamic indicators column.
        return onEditIndicatorValue;
    }
  };

  const getModalOnSelect = () => {
    switch (modalKey) {
      case MODAL_KEYS.SELECT_ITEM:
        return onAddRequisitionItem;
      case MODAL_KEYS.SELECT_MONTH:
        return onEditMonth;
      case MODAL_KEYS.REQUISITION_COMMENT_EDIT:
        return onEditComment;
      case MODAL_KEYS.SELECT_MASTER_LISTS:
        return onApplyMasterLists;
      default:
        return null;
    }
  };

  const renderRow = useCallback(
    listItem => {
      const { item, index } = listItem;
      const rowKey = keyExtractor(item);

      return (
        <DataTableRow
          rowData={data[index]}
          rowState={dataState.get(rowKey)}
          rowKey={rowKey}
          columns={columns}
          isFinalised={isFinalised}
          getCallback={getCallback}
          rowIndex={index}
        />
      );
    },
    [columns, data, dataState]
  );

  const renderHeader = useCallback(
    () => (
      <DataTableHeaderRow
        columns={columns}
        onPress={onSortColumn}
        isAscending={isAscending}
        sortKey={sortKey}
      />
    ),
    [columns, sortKey, isAscending]
  );

  const AddMasterListItemsButton = () => (
    <PageButton
      style={globalStyles.leftButton}
      text={buttonStrings.add_master_list_items}
      onPress={onAddMasterList}
      onSelect={onApplyMasterLists}
      isDisabled={isFinalised}
    />
  );

  const AddNewItemButton = () => (
    <PageButton
      style={globalStyles.topButton}
      text={buttonStrings.new_item}
      onPress={onSelectNewItem}
      isDisabled={isFinalised}
    />
  );

  const CreateAutomaticOrderButton = () => (
    <PageButton
      style={{ ...globalStyles.leftButton, marginLeft: 5 }}
      text={buttonStrings.create_automatic_order}
      onPress={onCreateAutomaticOrder}
      isDisabled={isFinalised}
    />
  );

  const UseSuggestedQuantitiesButton = () => (
    <PageButton
      style={program ? globalStyles.wideButton : globalStyles.topButton}
      text={buttonStrings.use_suggested_quantities}
      onPress={onSetRequestedToSuggested}
      isDisabled={isFinalised}
    />
  );

  const ItemIndicatorToggles = useMemo(
    () => [
      {
        text: programStrings.items,
        isOn: !showIndicators,
        onPress: onToggleIndicators,
      },
      {
        text: programStrings.indicators,
        isOn: showIndicators,
        onPress: onToggleIndicators,
      },
    ],
    [showIndicators]
  );

  const ThresholdMOSToggles = useMemo(
    () => [
      {
        text: programStrings.hide_over_stocked,
        isOn: !showAll,
        onPress: onHideOverStocked,
      },
      {
        text: programStrings.show_over_stocked,
        isOn: showAll,
        onPress: onShowOverStocked,
      },
    ],
    [showAll]
  );

  const ItemIndicatorToggle = () => <ToggleBar toggles={ItemIndicatorToggles} />;

  const ThresholdMOSToggle = () => <ToggleBar toggles={ThresholdMOSToggles} />;

  const GeneralButtons = useCallback(() => {
    const { verticalContainer } = globalStyles;
    return (
      <>
        <View style={verticalContainer}>
          <UseSuggestedQuantitiesButton />
          <CreateAutomaticOrderButton />
        </View>
        <View style={verticalContainer}>
          <AddNewItemButton />
          <AddMasterListItemsButton />
        </View>
      </>
    );
  }, [isFinalised]);

  const ProgramItemButtons = useCallback(
    () => (
      <View style={globalStyles.verticalContainer}>
        <UseSuggestedQuantitiesButton />
        <ThresholdMOSToggle />
      </View>
    ),
    [UseSuggestedQuantitiesButton, ThresholdMOSToggle]
  );

  const ProgramIndicatorButtons = useCallback(
    () => (
      <>
        <DropDown
          values={indicatorCodes}
          selectedValue={currentIndicatorCode}
          onValueChange={onSelectIndicator}
          style={globalStyles.pickerTall}
        />
      </>
    ),
    [indicatorCodes, currentIndicatorCode]
  );

  const ProgramButtons = useCallback(() => {
    if (usingIndicators) {
      const Buttons = showIndicators ? ProgramIndicatorButtons : ProgramItemButtons;
      return (
        <View style={globalStyles.verticalContainer}>
          <ItemIndicatorToggle />
          <Buttons />
        </View>
      );
    }
    return <ProgramItemButtons />;
  }, [usingIndicators, showIndicators, showAll, indicatorCodes, currentIndicatorCode, isFinalised]);

  const placeholderStrings = useMemo(
    () => ({
      name: showIndicators ? generalStrings.indicator_name : generalStrings.item_name,
      code: showIndicators ? generalStrings.indicator_code : generalStrings.item_code,
    }),
    [showIndicators]
  );

  const {
    pageTopSectionContainer,
    pageTopLeftSectionContainer,
    pageTopRightSectionContainer,
  } = globalStyles;

  return (
    <DataTablePageView>
      <View style={pageTopSectionContainer}>
        <View style={pageTopLeftSectionContainer}>
          <PageInfo columns={pageInfoColumns} isEditingDisabled={isFinalised} />
          <SearchBar
            onChangeText={onFilterData}
            value={searchTerm}
            placeholder={`${generalStrings.search_by} ${placeholderStrings.name} ${generalStrings.or} ${placeholderStrings.code}`}
          />
        </View>
        <View style={pageTopRightSectionContainer}>
          {program ? <ProgramButtons /> : <GeneralButtons />}
        </View>
      </View>
      <DataTable
        data={data}
        extraData={dataState}
        renderRow={renderRow}
        renderHeader={renderHeader}
        keyExtractor={keyExtractor}
        getItemLayout={getItemLayout}
        columns={columns}
        windowSize={
          showIndicators
            ? DATA_TABLE_DEFAULTS.WINDOW_SIZE_SMALL
            : DATA_TABLE_DEFAULTS.WINDOW_SIZE_MEDIUM
        }
      />
      <BottomConfirmModal
        isOpen={hasSelection}
        questionText={modalStrings.remove_these_items}
        onCancel={onDeselectAll}
        onConfirm={onDeleteItems}
        confirmText={modalStrings.remove}
      />
      <DataTablePageModal
        fullScreen={false}
        isOpen={!!modalKey}
        modalKey={modalKey}
        onClose={onCloseModal}
        onSelect={getModalOnSelect()}
        dispatch={dispatch}
        currentValue={modalValue}
      />
    </DataTablePageView>
  );
};

const mapDispatchToProps = (dispatch, ownProps) => {
  const thisStoreID = UIDatabase.getSetting(SETTINGS_KEYS.THIS_STORE_NAME_ID);
  const thisStore = UIDatabase.get('Name', thisStoreID);
  const hasMasterLists = thisStore?.masterLists?.length > 0;

  const noMasterLists = () =>
    ToastAndroid.show(modalStrings.supplier_no_masterlist_available, ToastAndroid.LONG);

  return {
    ...getPageDispatchers(dispatch, ownProps, 'Requisition', ROUTES.SUPPLIER_REQUISITION),
    [hasMasterLists ? null : 'onAddMasterList']: noMasterLists,
  };
};

const mapStateToProps = state => {
  const { pages } = state;
  const supplierRequisition = pages[ROUTES.SUPPLIER_REQUISITION];
  const { usingIndicators, showIndicators } = supplierRequisition;

  if (usingIndicators && showIndicators) {
    return {
      ...supplierRequisition,
      indicatorCodes: selectIndicatorCodes(supplierRequisition),
      currentIndicatorCode: selectCurrentIndicatorCode(supplierRequisition),
      data: selectIndicatorTableRows(supplierRequisition),
      columns: selectIndicatorTableColumns(supplierRequisition),
    };
  }
  return pages[ROUTES.SUPPLIER_REQUISITION];
};

export const SupplierRequisitionPage = connect(
  mapStateToProps,
  mapDispatchToProps
)(SupplierRequisition);

SupplierRequisition.defaultProps = {
  modalValue: null,
  showAll: false,
  usingIndicators: false,
  showIndicators: false,
  indicatorCodes: [],
  currentIndicatorCode: '',
};

SupplierRequisition.propTypes = {
  dispatch: PropTypes.func.isRequired,
  data: PropTypes.array.isRequired,
  sortKey: PropTypes.string.isRequired,
  isAscending: PropTypes.bool.isRequired,
  searchTerm: PropTypes.string.isRequired,
  columns: PropTypes.array.isRequired,
  keyExtractor: PropTypes.func.isRequired,
  runWithLoadingIndicator: PropTypes.func.isRequired,
  dataState: PropTypes.object.isRequired,
  modalKey: PropTypes.string.isRequired,
  pageObject: PropTypes.object.isRequired,
  getPageInfoColumns: PropTypes.func.isRequired,
  routeName: PropTypes.string.isRequired,
  hasSelection: PropTypes.bool.isRequired,
  showAll: PropTypes.bool,
  usingIndicators: PropTypes.bool,
  showIndicators: PropTypes.bool,
  currentIndicatorCode: PropTypes.string,
  indicatorCodes: PropTypes.array,
  modalValue: PropTypes.any,
  refreshData: PropTypes.func.isRequired,
  onSelectNewItem: PropTypes.func.isRequired,
  onEditComment: PropTypes.func.isRequired,
  onFilterData: PropTypes.func.isRequired,
  onDeleteItems: PropTypes.func.isRequired,
  onDeselectAll: PropTypes.func.isRequired,
  onCloseModal: PropTypes.func.isRequired,
  onCheck: PropTypes.func.isRequired,
  onUncheck: PropTypes.func.isRequired,
  onSortColumn: PropTypes.func.isRequired,
  onToggleIndicators: PropTypes.func.isRequired,
  onShowOverStocked: PropTypes.func.isRequired,
  onHideOverStocked: PropTypes.func.isRequired,
  onSelectIndicator: PropTypes.func.isRequired,
  onEditIndicatorValue: PropTypes.func.isRequired,
  onEditMonth: PropTypes.func.isRequired,
  onEditRequiredQuantity: PropTypes.func.isRequired,
  onAddRequisitionItem: PropTypes.func.isRequired,
  onSetRequestedToSuggested: PropTypes.func.isRequired,
  onAddMasterList: PropTypes.func.isRequired,
  onApplyMasterLists: PropTypes.func.isRequired,
  route: PropTypes.string.isRequired,
};
<commit_msg>Add logic to apply reasons<commit_after>/* eslint-disable react/no-unused-prop-types */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { View, ToastAndroid } from 'react-native';
import { connect } from 'react-redux';

import { MODAL_KEYS } from '../utilities';
import { DataTablePageModal } from '../widgets/modals';
import { BottomConfirmModal } from '../widgets/bottomModals';
import { DataTable, DataTableHeaderRow, DataTableRow } from '../widgets/DataTable';
import { DATA_TABLE_DEFAULTS } from '../widgets/DataTable/constants';
import {
  DataTablePageView,
  DropDown,
  PageButton,
  PageInfo,
  ToggleBar,
  SearchBar,
} from '../widgets';

import {
  selectIndicatorCodes,
  selectCurrentIndicatorCode,
  selectIndicatorTableColumns,
  selectIndicatorTableRows,
} from '../selectors/indicatorSelectors';
import { getItemLayout, getPageDispatchers, PageActions } from './dataTableUtilities';

import { ROUTES } from '../navigation/constants';

import { useRecordListener } from '../hooks';

import globalStyles from '../globalStyles';
import { buttonStrings, modalStrings, programStrings, generalStrings } from '../localization';
import { UIDatabase } from '../database/index';
import { SETTINGS_KEYS } from '../settings/index';

/**
 * Renders a mSupply mobile page with a supplier requisition loaded for editing
 *
 * State:
 * Uses a reducer to manage state with `backingData` being a realm results
 * of items to display. `data` is a plain JS array of realm objects. data is
 * hydrated from the `backingData` for displaying in the interface.
 * i.e: When filtering, data is populated from filtered items of `backingData`.
 *
 * dataState is a simple map of objects corresponding to a row being displayed,
 * holding the state of a given row. Each object has the shape :
 * { isSelected, isDisabled },
 */
const SupplierRequisition = ({
  runWithLoadingIndicator,
  dispatch,
  data,
  dataState,
  sortKey,
  modalValue,
  isAscending,
  modalKey,
  pageObject,
  hasSelection,
  showAll,
  usingIndicators,
  showIndicators,
  currentIndicatorCode,
  indicatorCodes,
  keyExtractor,
  searchTerm,
  columns,
  getPageInfoColumns,
  refreshData,
  onSelectNewItem,
  onEditComment,
  onFilterData,
  onDeleteItems,
  onDeselectAll,
  onCloseModal,
  onCheck,
  onUncheck,
  onSortColumn,
  onToggleIndicators,
  onSelectIndicator,
  onEditIndicatorValue,
  onShowOverStocked,
  onHideOverStocked,
  onEditMonth,
  onEditRequiredQuantity,
  onAddRequisitionItem,
  onSetRequestedToSuggested,
  onAddMasterList,
  onApplyMasterLists,
  onEditRequiredQuantityWithReason,
  onEditRequisitionReason,
  onApplyReason,
  route,
}) => {
  // Listen for changes to this pages requisition. Refreshing data on side effects i.e. finalizing.
  useRecordListener(() => dispatch(refreshData), pageObject, 'Requisition');

  const usingReasons = !!UIDatabase.objects('RequisitionReason').length;

  const { isFinalised, comment, theirRef, program, daysToSupply } = pageObject;

  const createAutomaticOrder = () => dispatch(PageActions.createAutomaticOrder(route));
  const onCreateAutomaticOrder = () => runWithLoadingIndicator(createAutomaticOrder);

  const pageInfoColumns = useMemo(() => getPageInfoColumns(pageObject, dispatch, route), [
    comment,
    theirRef,
    isFinalised,
    daysToSupply,
  ]);

  const getCallback = (colKey, propName) => {
    switch (colKey) {
      case 'requiredQuantity':
        return usingReasons ? onEditRequiredQuantityWithReason : onEditRequiredQuantity;
      case 'remove':
        if (propName === 'onCheck') return onCheck;
        return onUncheck;
      case 'reasonTitle':
        return onEditRequisitionReason;
      default:
        // Indicators functionality generates columns at run-time from indicator attribute
        // data. If known column key not found, assume column is a dynamic indicators column.
        return onEditIndicatorValue;
    }
  };

  const getModalOnSelect = () => {
    switch (modalKey) {
      case MODAL_KEYS.SELECT_ITEM:
        return onAddRequisitionItem;
      case MODAL_KEYS.SELECT_MONTH:
        return onEditMonth;
      case MODAL_KEYS.REQUISITION_COMMENT_EDIT:
        return onEditComment;
      case MODAL_KEYS.SELECT_MASTER_LISTS:
        return onApplyMasterLists;
      case MODAL_KEYS.ENFORCE_REQUISITION_REASON:
      case MODAL_KEYS.REQUISITION_REASON:
        return onApplyReason;
      default:
        return null;
    }
  };

  const renderRow = useCallback(
    listItem => {
      const { item, index } = listItem;
      const rowKey = keyExtractor(item);

      return (
        <DataTableRow
          rowData={data[index]}
          rowState={dataState.get(rowKey)}
          rowKey={rowKey}
          columns={columns}
          isFinalised={isFinalised}
          getCallback={getCallback}
          rowIndex={index}
        />
      );
    },
    [columns, data, dataState]
  );

  const renderHeader = useCallback(
    () => (
      <DataTableHeaderRow
        columns={columns}
        onPress={onSortColumn}
        isAscending={isAscending}
        sortKey={sortKey}
      />
    ),
    [columns, sortKey, isAscending]
  );

  const AddMasterListItemsButton = () => (
    <PageButton
      style={globalStyles.leftButton}
      text={buttonStrings.add_master_list_items}
      onPress={onAddMasterList}
      onSelect={onApplyMasterLists}
      isDisabled={isFinalised}
    />
  );

  const AddNewItemButton = () => (
    <PageButton
      style={globalStyles.topButton}
      text={buttonStrings.new_item}
      onPress={onSelectNewItem}
      isDisabled={isFinalised}
    />
  );

  const CreateAutomaticOrderButton = () => (
    <PageButton
      style={{ ...globalStyles.leftButton, marginLeft: 5 }}
      text={buttonStrings.create_automatic_order}
      onPress={onCreateAutomaticOrder}
      isDisabled={isFinalised}
    />
  );

  const UseSuggestedQuantitiesButton = () => (
    <PageButton
      style={program ? globalStyles.wideButton : globalStyles.topButton}
      text={buttonStrings.use_suggested_quantities}
      onPress={onSetRequestedToSuggested}
      isDisabled={isFinalised}
    />
  );

  const ItemIndicatorToggles = useMemo(
    () => [
      {
        text: programStrings.items,
        isOn: !showIndicators,
        onPress: onToggleIndicators,
      },
      {
        text: programStrings.indicators,
        isOn: showIndicators,
        onPress: onToggleIndicators,
      },
    ],
    [showIndicators]
  );

  const ThresholdMOSToggles = useMemo(
    () => [
      {
        text: programStrings.hide_over_stocked,
        isOn: !showAll,
        onPress: onHideOverStocked,
      },
      {
        text: programStrings.show_over_stocked,
        isOn: showAll,
        onPress: onShowOverStocked,
      },
    ],
    [showAll]
  );

  const ItemIndicatorToggle = () => <ToggleBar toggles={ItemIndicatorToggles} />;

  const ThresholdMOSToggle = () => <ToggleBar toggles={ThresholdMOSToggles} />;

  const GeneralButtons = useCallback(() => {
    const { verticalContainer } = globalStyles;
    return (
      <>
        <View style={verticalContainer}>
          <UseSuggestedQuantitiesButton />
          <CreateAutomaticOrderButton />
        </View>
        <View style={verticalContainer}>
          <AddNewItemButton />
          <AddMasterListItemsButton />
        </View>
      </>
    );
  }, [isFinalised]);

  const ProgramItemButtons = useCallback(
    () => (
      <View style={globalStyles.verticalContainer}>
        <UseSuggestedQuantitiesButton />
        <ThresholdMOSToggle />
      </View>
    ),
    [UseSuggestedQuantitiesButton, ThresholdMOSToggle]
  );

  const ProgramIndicatorButtons = useCallback(
    () => (
      <>
        <DropDown
          values={indicatorCodes}
          selectedValue={currentIndicatorCode}
          onValueChange={onSelectIndicator}
          style={globalStyles.pickerTall}
        />
      </>
    ),
    [indicatorCodes, currentIndicatorCode]
  );

  const ProgramButtons = useCallback(() => {
    if (usingIndicators) {
      const Buttons = showIndicators ? ProgramIndicatorButtons : ProgramItemButtons;
      return (
        <View style={globalStyles.verticalContainer}>
          <ItemIndicatorToggle />
          <Buttons />
        </View>
      );
    }
    return <ProgramItemButtons />;
  }, [usingIndicators, showIndicators, showAll, indicatorCodes, currentIndicatorCode, isFinalised]);

  const placeholderStrings = useMemo(
    () => ({
      name: showIndicators ? generalStrings.indicator_name : generalStrings.item_name,
      code: showIndicators ? generalStrings.indicator_code : generalStrings.item_code,
    }),
    [showIndicators]
  );

  const {
    pageTopSectionContainer,
    pageTopLeftSectionContainer,
    pageTopRightSectionContainer,
  } = globalStyles;

  return (
    <DataTablePageView>
      <View style={pageTopSectionContainer}>
        <View style={pageTopLeftSectionContainer}>
          <PageInfo columns={pageInfoColumns} isEditingDisabled={isFinalised} />
          <SearchBar
            onChangeText={onFilterData}
            value={searchTerm}
            placeholder={`${generalStrings.search_by} ${placeholderStrings.name} ${generalStrings.or} ${placeholderStrings.code}`}
          />
        </View>
        <View style={pageTopRightSectionContainer}>
          {program ? <ProgramButtons /> : <GeneralButtons />}
        </View>
      </View>
      <DataTable
        data={data}
        extraData={dataState}
        renderRow={renderRow}
        renderHeader={renderHeader}
        keyExtractor={keyExtractor}
        getItemLayout={getItemLayout}
        columns={columns}
        windowSize={
          showIndicators
            ? DATA_TABLE_DEFAULTS.WINDOW_SIZE_SMALL
            : DATA_TABLE_DEFAULTS.WINDOW_SIZE_MEDIUM
        }
      />
      <BottomConfirmModal
        isOpen={hasSelection}
        questionText={modalStrings.remove_these_items}
        onCancel={onDeselectAll}
        onConfirm={onDeleteItems}
        confirmText={modalStrings.remove}
      />
      <DataTablePageModal
        fullScreen={false}
        isOpen={!!modalKey}
        modalKey={modalKey}
        onClose={onCloseModal}
        onSelect={getModalOnSelect()}
        dispatch={dispatch}
        currentValue={modalValue}
      />
    </DataTablePageView>
  );
};

const mapDispatchToProps = (dispatch, ownProps) => {
  const thisStoreID = UIDatabase.getSetting(SETTINGS_KEYS.THIS_STORE_NAME_ID);
  const thisStore = UIDatabase.get('Name', thisStoreID);
  const hasMasterLists = thisStore?.masterLists?.length > 0;

  const noMasterLists = () =>
    ToastAndroid.show(modalStrings.supplier_no_masterlist_available, ToastAndroid.LONG);

  return {
    ...getPageDispatchers(dispatch, ownProps, 'Requisition', ROUTES.SUPPLIER_REQUISITION),
    [hasMasterLists ? null : 'onAddMasterList']: noMasterLists,
  };
};

const mapStateToProps = state => {
  const { pages } = state;
  const supplierRequisition = pages[ROUTES.SUPPLIER_REQUISITION];
  const { usingIndicators, showIndicators } = supplierRequisition;

  if (usingIndicators && showIndicators) {
    return {
      ...supplierRequisition,
      indicatorCodes: selectIndicatorCodes(supplierRequisition),
      currentIndicatorCode: selectCurrentIndicatorCode(supplierRequisition),
      data: selectIndicatorTableRows(supplierRequisition),
      columns: selectIndicatorTableColumns(supplierRequisition),
    };
  }
  return pages[ROUTES.SUPPLIER_REQUISITION];
};

export const SupplierRequisitionPage = connect(
  mapStateToProps,
  mapDispatchToProps
)(SupplierRequisition);

SupplierRequisition.defaultProps = {
  modalValue: null,
  showAll: false,
  usingIndicators: false,
  showIndicators: false,
  indicatorCodes: [],
  currentIndicatorCode: '',
};

SupplierRequisition.propTypes = {
  dispatch: PropTypes.func.isRequired,
  data: PropTypes.array.isRequired,
  sortKey: PropTypes.string.isRequired,
  isAscending: PropTypes.bool.isRequired,
  searchTerm: PropTypes.string.isRequired,
  columns: PropTypes.array.isRequired,
  keyExtractor: PropTypes.func.isRequired,
  runWithLoadingIndicator: PropTypes.func.isRequired,
  dataState: PropTypes.object.isRequired,
  modalKey: PropTypes.string.isRequired,
  pageObject: PropTypes.object.isRequired,
  getPageInfoColumns: PropTypes.func.isRequired,
  routeName: PropTypes.string.isRequired,
  hasSelection: PropTypes.bool.isRequired,
  showAll: PropTypes.bool,
  usingIndicators: PropTypes.bool,
  showIndicators: PropTypes.bool,
  currentIndicatorCode: PropTypes.string,
  indicatorCodes: PropTypes.array,
  modalValue: PropTypes.any,
  refreshData: PropTypes.func.isRequired,
  onSelectNewItem: PropTypes.func.isRequired,
  onEditComment: PropTypes.func.isRequired,
  onFilterData: PropTypes.func.isRequired,
  onDeleteItems: PropTypes.func.isRequired,
  onDeselectAll: PropTypes.func.isRequired,
  onCloseModal: PropTypes.func.isRequired,
  onCheck: PropTypes.func.isRequired,
  onUncheck: PropTypes.func.isRequired,
  onSortColumn: PropTypes.func.isRequired,
  onToggleIndicators: PropTypes.func.isRequired,
  onShowOverStocked: PropTypes.func.isRequired,
  onHideOverStocked: PropTypes.func.isRequired,
  onSelectIndicator: PropTypes.func.isRequired,
  onEditIndicatorValue: PropTypes.func.isRequired,
  onEditMonth: PropTypes.func.isRequired,
  onEditRequiredQuantity: PropTypes.func.isRequired,
  onAddRequisitionItem: PropTypes.func.isRequired,
  onSetRequestedToSuggested: PropTypes.func.isRequired,
  onAddMasterList: PropTypes.func.isRequired,
  onApplyMasterLists: PropTypes.func.isRequired,
  route: PropTypes.string.isRequired,
  onEditRequiredQuantityWithReason: PropTypes.func.isRequired,
  onEditRequisitionReason: PropTypes.func.isRequired,
  onApplyReason: PropTypes.func.isRequired,
};
<|endoftext|>


<commit_before>import { BrowserWindow } from 'electron';
import validateAction from '../helpers/validateAction';

const forwardToRenderer = () => next => (action) => {
  if (!validateAction(action)) return next(action);
  if (action.meta && action.meta.scope === 'local') return next(action);

  // change scope to avoid endless-loop
  const rendererAction = {
    ...action,
    meta: {
      ...action.meta,
      scope: 'local',
    },
  };

  const openWindows = BrowserWindow.getAllWindows();
  openWindows.forEach(({ webContents }) => {
    webContents.send('redux-action', rendererAction);
  });

  return next(action);
};

export default forwardToRenderer;
<commit_msg>Forward to all webContents instead.<commit_after>import { webContents } from 'electron';
import validateAction from '../helpers/validateAction';

const forwardToRenderer = () => next => (action) => {
  if (!validateAction(action)) return next(action);
  if (action.meta && action.meta.scope === 'local') return next(action);

  // change scope to avoid endless-loop
  const rendererAction = {
    ...action,
    meta: {
      ...action.meta,
      scope: 'local',
    },
  };

  const allWebContents = webContents.getAllWebContents();

  allWebContents.forEach((contents) => {
    contents.send('redux-action', rendererAction);
  });

  return next(action);
};

export default forwardToRenderer;
<|endoftext|>


<commit_before>import { arc } from 'd3-shape';
import getLevels from './grid-levels';

const drawAxisLabel = (context, state, opt, innerRadius, outerRadius)=> {
    const levels = getLevels(opt);

    const gridArc = arc()
        .innerRadius(outerRadius)
        .outerRadius(outerRadius)
        .startAngle(0)
        .endAngle(2 * Math.PI)
        .context(context);

    for (let i = 1; i < levels + 1; i++) {
        context.beginPath();
        context.strokeStyle = opt.plots.levelColor;
        gridArc(i);
        context.stroke();
    }
}

export default drawAxisLabel;
<commit_msg>axis label<commit_after>import { arc } from 'd3-shape';
import getLevels from './grid-levels';

const drawAxisLabel = (context, state, opt, innerRadius, outerRadius)=> {
    const gridArc = arc()
        .innerRadius(outerRadius)
        .outerRadius(outerRadius)
        .startAngle(0)
        .endAngle(2 * Math.PI)
        .context(context);

    for (let i = 1; i < levels + 1; i++) {
        context.beginPath();
        context.strokeStyle = opt.plots.levelColor;
        gridArc(i);
        context.stroke();
    }
}

export default drawAxisLabel;
<|endoftext|>


<commit_before>import {Vector3} from 'three';
import {ThreeOrbitControls} from './lib/ThreeOrbitControls';

export class OrbitModule {
  constructor(params = {}) {
    this.params = Object.assign({
      target: new Vector3(0, 0, 0),
      follow: false
    }, params);
  }

  manager(manager) {
    this.controls = new ThreeOrbitControls(
      manager.get('camera').native,
      manager.get('renderer').domElement
    );

    manager.update({
      camera: (camera) => {
        this.controls.object = camera.native;
      }
    });
  }

  integrate(self) {
    const {params, controls} = self;

    const updateProcessor = params.follow ? (c) => {
      controls.update(c.getDelta());
      controls.target.copy(params.target);
    } : (c) => {
      controls.update(c.getDelta());
    };

    self.updateLoop = new WHS.Loop(updateProcessor).start(this);

    controls.target.copy(params.target);
  }
}
<commit_msg>Fix Loop dependency in OrbitControls<commit_after>import {Vector3} from 'three';

import {Loop} from '../../core/Loop';
import {ThreeOrbitControls} from './lib/ThreeOrbitControls';

export class OrbitModule {
  constructor(params = {}) {
    this.params = Object.assign({
      target: new Vector3(0, 0, 0),
      follow: false
    }, params);
  }

  manager(manager) {
    this.controls = new ThreeOrbitControls(
      manager.get('camera').native,
      manager.get('renderer').domElement
    );

    manager.update({
      camera: (camera) => {
        this.controls.object = camera.native;
      }
    });
  }

  integrate(self) {
    const {params, controls} = self;

    const updateProcessor = params.follow ? (c) => {
      controls.update(c.getDelta());
      controls.target.copy(params.target);
    } : (c) => {
      controls.update(c.getDelta());
    };

    self.updateLoop = new Loop(updateProcessor).start(this);

    controls.target.copy(params.target);
  }
}
<|endoftext|>


<commit_before>'use strict';
/* Node to all from OHAD 17.4.16
    If you want to add new search type, you will need to add new "row-type" that show your data.
    So you need to write this "row-type" שccording to your needs and how your data was written.
    More INFO: in the "var templates" below you need to add :
    "'search-[name of type]': '/icu/components/row-types/search-[name of type]-row.html'"
    And of course add the file there.
    Also, need to add route in: "/icu/packages/custom/icu/public/app/app.js".
    Add folder of the details of the type (in the right side). Like "/icu/packages/custom/icu/public/components/task-details"
*/
angular.module('mean.icu.ui.rows', [])
.directive('icuListRow', function($compile, $http, $templateRequest, $i18next, UsersService, PermissionsService) {
    var templates = {
        people: '/icu/components/row-types/people-row.html',
        task: '/icu/components/row-types/task-row.html',
        project: '/icu/components/row-types/project-row.html',
        discussion: '/icu/components/row-types/discussion-row.html',
        office: '/icu/components/row-types/office-row.html',
        templateDoc: '/icu/components/row-types/templateDoc-row.html',
        folder: '/icu/components/row-types/folder-row.html',
        officeDocument: '/icu/components/row-types/officeDocument-row.html',
//        officedocument: '/icu/components/row-types/officeDocument-row.html',
        'search-task': '/icu/components/row-types/search-task-row.html',
        'search-project': '/icu/components/row-types/search-project-row.html',
        'search-discussion': '/icu/components/row-types/search-discussion-row.html',
        'search-attachment': '/icu/components/row-types/search-attachment-row.html',
        'search-vg-files': '/icu/components/row-types/search-attachment-row.html',
        'search-update': '/icu/components/row-types/search-update-row.html',
        'search-office': '/icu/components/row-types/search-office-row.html',
        'search-folder': '/icu/components/row-types/search-folder-row.html',
        'search-officeDocument': '/icu/components/row-types/search-officeDocument-row.html',
        'search-officedocument': '/icu/components/row-types/search-officeDocument-row.html',
        'search-templateDoc': '/icu/components/row-types/search-templateDoc-row.html',
        'subtasks': '/icu/components/row-types/sub-tasks-row.html',
        'subprojects': '/icu/components/row-types/sub-projects-row.html',
    };

    function compileTemplate($scope, $element, template) {
        $element.html(template);
        var scope = $scope.$new(true);
        scope.data = $scope.data;
        $compile($element.contents())(scope);
    }

    //This way has caused problems with $index
    function link($scope, $element) {
        if ($scope.type.indexOf('search') > -1) {
	        var templateUrl = templates[$scope.type];
	        $templateRequest(templateUrl).then(function(result) {
	            compileTemplate($scope, $element, result);
	        });
		}
        if ($scope.data[$scope.type] && $scope.data[$scope.type].due) {
            $scope.data[$scope.type].due = new Date($scope.data[$scope.type].due)
        }
        $scope.me = {};
            UsersService.getMe().then(function(me) {
                $scope.me = me;
        });

        $scope.recycled = function(entity){
            if(entity && entity.hasOwnProperty('recycled'))return true;
            return false;
        };

        $scope.havePermissions = function(entity, type){
            return PermissionsService.havePermissions(entity, type);
        };

        $scope.haveEditiorsPermissions = function(entity){
            if(!entity.permissions)return true;
            return PermissionsService.haveEditorsPerms(entity);
        };

        $scope.permsToSee = function(entity){
            return PermissionsService.haveAnyPerms(entity);
        };

        var lang = $i18next.options.lng;
        $scope.leftDirection = function(entity){
            return !entity.focus && lang ==='en';
        };
        $scope.rightDirection =  function(entity){
            return !entity.focus && lang ==='he';
        };

        $scope.focusing = function(entity){
            entity.focus = true;
        };
        $scope.bluring = function(entity, $event){
            entity.focus = false;
            if($event.target.children.length == 0){
                $event.target.scrollLeft = 0;
            } else {
                $event.target.firstChild.scrollLeft = 0;
            }
        };
    }

    return {
        restrict: 'A',
        scope: {
            type: '@',
            data: '='
        },
        link: link,
        transclude: true,
        templateUrl: function (tElement, tAttrs) {
            if (tAttrs.type.indexOf('search') === -1) {
	            return templates[tAttrs.type];
	        } else {
	        	return '/icu/components/row-types/empty-row.html';
	        }
        }
    };
});
<commit_msg>fixed showing the beginning of the title in middle pane in hebrew<commit_after>'use strict';
/* Node to all from OHAD 17.4.16
    If you want to add new search type, you will need to add new "row-type" that show your data.
    So you need to write this "row-type" שccording to your needs and how your data was written.
    More INFO: in the "var templates" below you need to add :
    "'search-[name of type]': '/icu/components/row-types/search-[name of type]-row.html'"
    And of course add the file there.
    Also, need to add route in: "/icu/packages/custom/icu/public/app/app.js".
    Add folder of the details of the type (in the right side). Like "/icu/packages/custom/icu/public/components/task-details"
*/
angular.module('mean.icu.ui.rows', [])
.directive('icuListRow', function($compile, $http, $templateRequest, $i18next, UsersService, PermissionsService) {
    var templates = {
        people: '/icu/components/row-types/people-row.html',
        task: '/icu/components/row-types/task-row.html',
        project: '/icu/components/row-types/project-row.html',
        discussion: '/icu/components/row-types/discussion-row.html',
        office: '/icu/components/row-types/office-row.html',
        templateDoc: '/icu/components/row-types/templateDoc-row.html',
        folder: '/icu/components/row-types/folder-row.html',
        officeDocument: '/icu/components/row-types/officeDocument-row.html',
//        officedocument: '/icu/components/row-types/officeDocument-row.html',
        'search-task': '/icu/components/row-types/search-task-row.html',
        'search-project': '/icu/components/row-types/search-project-row.html',
        'search-discussion': '/icu/components/row-types/search-discussion-row.html',
        'search-attachment': '/icu/components/row-types/search-attachment-row.html',
        'search-vg-files': '/icu/components/row-types/search-attachment-row.html',
        'search-update': '/icu/components/row-types/search-update-row.html',
        'search-office': '/icu/components/row-types/search-office-row.html',
        'search-folder': '/icu/components/row-types/search-folder-row.html',
        'search-officeDocument': '/icu/components/row-types/search-officeDocument-row.html',
        'search-officedocument': '/icu/components/row-types/search-officeDocument-row.html',
        'search-templateDoc': '/icu/components/row-types/search-templateDoc-row.html',
        'subtasks': '/icu/components/row-types/sub-tasks-row.html',
        'subprojects': '/icu/components/row-types/sub-projects-row.html',
    };

    function compileTemplate($scope, $element, template) {
        $element.html(template);
        var scope = $scope.$new(true);
        scope.data = $scope.data;
        $compile($element.contents())(scope);
    }

    //This way has caused problems with $index
    function link($scope, $element) {
        if ($scope.type.indexOf('search') > -1) {
	        var templateUrl = templates[$scope.type];
	        $templateRequest(templateUrl).then(function(result) {
	            compileTemplate($scope, $element, result);
	        });
		}
        if ($scope.data[$scope.type] && $scope.data[$scope.type].due) {
            $scope.data[$scope.type].due = new Date($scope.data[$scope.type].due)
        }
        $scope.me = {};
            UsersService.getMe().then(function(me) {
                $scope.me = me;
        });

        $scope.recycled = function(entity){
            if(entity && entity.hasOwnProperty('recycled'))return true;
            return false;
        };

        $scope.havePermissions = function(entity, type){
            return PermissionsService.havePermissions(entity, type);
        };

        $scope.haveEditiorsPermissions = function(entity){
            if(!entity.permissions)return true;
            return PermissionsService.haveEditorsPerms(entity);
        };

        $scope.permsToSee = function(entity){
            return PermissionsService.haveAnyPerms(entity);
        };

        var lang = $i18next.options.lng;
        $scope.leftDirection = function(entity){
            return !entity.focus && lang ==='en';
        };
        $scope.rightDirection =  function(entity){
            return !entity.focus && lang ==='he';
        };

        var lang = $i18next.options.lng;

        $scope.focusing = function(entity){
            entity.focus = true;
        };
        $scope.bluring = function(entity, $event){
            entity.focus = false;
            var scrollLeft = function(element){
                element.scrollLeft = 0;
            };
            var scrollRight = function(element){
                element.scrollLeft += $event.target.scrollWidth - $event.target.scrollLeft;
            };

            if(lang === 'en'){
                $event.target.children.length === 0 ? scrollLeft($event.target) : scrollLeft($event.target.firstChild);
            } else if(lang === 'he') {
                $event.target.children.length === 0 ? scrollRight($event.target) : scrollRight($event.target.firstChild);
            }
        };
    }

    return {
        restrict: 'A',
        scope: {
            type: '@',
            data: '='
        },
        link: link,
        transclude: true,
        templateUrl: function (tElement, tAttrs) {
            if (tAttrs.type.indexOf('search') === -1) {
	            return templates[tAttrs.type];
	        } else {
	        	return '/icu/components/row-types/empty-row.html';
	        }
        }
    };
});
<|endoftext|>


<commit_before>import fs from 'fs'
import path from 'path'
import semver from 'semver'

const writePackageJsonsForAssemblies = (
  distDir,
  nodeModulesByAssembly,
  peerDependencies
) => {
  const applicationPackageJson = JSON.parse(
    fs.readFileSync(path.resolve(process.cwd(), 'package.json'))
  )

  for (const [
    packageJsonPath,
    nodeModules,
  ] of nodeModulesByAssembly.entries()) {
    const absolutePackageJsonPath = path.resolve(
      process.cwd(),
      distDir,
      packageJsonPath
    )

    const syntheticName = packageJsonPath
      .replace('/package.json', '')
      .replace(/[^\w\d-]/g, '-')

    const resultNodeModules = new Set([
      ...Array.from(nodeModules),
      ...Array.from(peerDependencies),
    ])

    const frameworkVersions = Array.from(
      new Set(
        Object.entries(applicationPackageJson.dependencies)
          .filter(([dependency]) => dependency.startsWith('@resolve-js/'))
          .map(([, version]) => {
            const parsedVersion = semver.parse(version)
            return parsedVersion != null ? version : null
          })
          .filter((version) => version != null)
      )
    )

    if (frameworkVersions.length === 0) {
      throw new Error('package.json does not includes any framework packages')
    }

    if (frameworkVersions.length > 1) {
      throw new Error(
        `reSolve version is ${frameworkVersions[0]}, but expected ${frameworkVersions[1]}`
      )
    }

    const assemblyPackageJson = {
      name: `${applicationPackageJson.name}-${syntheticName}`,
      private: true,
      version: applicationPackageJson.version,
      main: './index.js',
      dependencies: Array.from(resultNodeModules).reduce((acc, val) => {
        if (applicationPackageJson.dependencies.hasOwnProperty(val)) {
          acc[val] = applicationPackageJson.dependencies[val]
        }

        return acc
      }, {}),
    }

    fs.writeFileSync(
      absolutePackageJsonPath,
      JSON.stringify(assemblyPackageJson, null, 2)
    )
  }
}

export default writePackageJsonsForAssemblies
<commit_msg>Fix create-resolve-app tests (#2258)<commit_after>import fs from 'fs'
import path from 'path'
import semver from 'semver'

const writePackageJsonsForAssemblies = (
  distDir,
  nodeModulesByAssembly,
  peerDependencies
) => {
  const applicationPackageJson = JSON.parse(
    fs.readFileSync(path.resolve(process.cwd(), 'package.json'))
  )

  for (const [
    packageJsonPath,
    nodeModules,
  ] of nodeModulesByAssembly.entries()) {
    const absolutePackageJsonPath = path.resolve(
      process.cwd(),
      distDir,
      packageJsonPath
    )

    const syntheticName = packageJsonPath
      .replace('/package.json', '')
      .replace(/[^\w\d-]/g, '-')

    const resultNodeModules = new Set([
      ...Array.from(nodeModules),
      ...Array.from(peerDependencies),
    ])

    const frameworkVersions = Array.from(
      new Set(
        Object.entries(applicationPackageJson.dependencies)
          .filter(([dependency]) => dependency.startsWith('@resolve-js/'))
          .map(([, version]) => {
            const parsedVersion = semver.parse(version)
            return parsedVersion != null ? version : null
          })
      )
    )

    if (frameworkVersions.length === 0) {
      throw new Error('package.json does not includes any framework packages')
    }

    if (frameworkVersions.length > 1) {
      throw new Error(
        `reSolve version is ${frameworkVersions[0]}, but expected ${frameworkVersions[1]}`
      )
    }

    const assemblyPackageJson = {
      name: `${applicationPackageJson.name}-${syntheticName}`,
      private: true,
      version: applicationPackageJson.version,
      main: './index.js',
      dependencies: Array.from(resultNodeModules).reduce((acc, val) => {
        if (applicationPackageJson.dependencies.hasOwnProperty(val)) {
          acc[val] = applicationPackageJson.dependencies[val]
        }

        return acc
      }, {}),
    }

    fs.writeFileSync(
      absolutePackageJsonPath,
      JSON.stringify(assemblyPackageJson, null, 2)
    )
  }
}

export default writePackageJsonsForAssemblies
<|endoftext|>


<commit_before>(function(){

	JenScript.AbstractGridPlugin = function(config) {
		this._init(config);
	};
	JenScript.Model.inheritPrototype(JenScript.AbstractGridPlugin, JenScript.Plugin);
	JenScript.Model.addMethods(JenScript.AbstractGridPlugin, {
		_init : function(config){
			config = config ||{};
			this.grids = [];
			this.sensible = 5;
			config.name = (config.name !== undefined)?config.name : 'AbstractGridPlugin';
			config.priority = -10000;
			this.gridOrientation = config.gridOrientation;
			this.gridColor = config.gridColor;
			var fn = function(g){};
			this.gridWidth =(config.gridWidth !== undefined)?config.gridWidth : 1;
			this.gridOpacity =(config.gridOpacity !== undefined)?config.gridOpacity : 1;
			this.onGridPress = (config.onGridPress !== undefined)?config.onGridPress : fn;
			this.onGridRelease = (config.onGridRelease !== undefined)?config.onGridRelease : fn;
			this.onGridEnter = (config.onGridEnter !== undefined)?config.onGridEnter : fn;
			this.onGridExit = (config.onGridExit !== undefined)?config.onGridExit : fn;
			this.onGrid = (config.onGrid !== undefined)?config.onGrid : fn;

			JenScript.Plugin.call(this,config);
		},

		onProjectionRegister : function(){
			var that = this;
			this.getProjection().addProjectionListener('boundChanged', function(){
				that.repaintPlugin();
			},that.toString());
		},

		onMove : function(evt,part,x,y){
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                var z = (this.gridOrientation === 'Vertical')?x:y;
                if(Math.abs(z - g.deviceValue) < this.sensible && !g.enter){
                	g.enter = true;
                	this.onGridEnter(g);
                	this.onGrid('enter',g);
                }else if(Math.abs(z - g.deviceValue) > this.sensible && g.enter){
                	g.enter = false;
                	this.onGridExit(g);
                	this.onGrid('exit',g);
                }
			}
		},

		onPress : function(evt,part,x,y){
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                if(g.enter){
                	this.onGridPress(g);
                	this.onGrid('press',g);
                }
			}
		},

		onRelease : function(evt,part,x,y){
			console.log("release")
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                console.log("release grid "+g.uservalue+" press "+g.press);
                if(g.press){
                	this.press = false;
                	this.onGridRelease(g);
                	this.onGrid('release',g);
                }
            }
		},

		/**
		 * provides method override to get grids manager that generates grids
		 */
		getGridManager : function(){
			throw new Error('Abstract, grid manager should be supplied.');
		},

		paintGrids : function(g2d,grids) {
			for (var i = 0; i < grids.length; i++) {
                var grid = grids[i];
                var gd = grid.deviceValue;
                var or = this.gridOrientation;
                var color = (this.gridColor !== undefined)?this.gridColor:this.getProjection().themeColor;
                var x1 = (or === 'Vertical')?gd:0;
                var y1 = (or === 'Vertical')?0:gd;
                var x2 = (or === 'Vertical')?gd:this.getProjection().getPixelWidth();
                var y2 = (or === 'Vertical')?this.getProjection().getPixelHeight():gd;
                var gridLine = new JenScript.SVGLine().Id('grid'+JenScript.sequenceId++).from(x1,y1).to(x2,y2).stroke(color).strokeWidth(this.gridWidth).strokeOpacity(this.gridOpacity).fillNone();
                grid.element = gridLine.toSVG();
                g2d.insertSVG(grid.element);
			}
	    },

		paintPlugin : function(g2d,part) {
	        if (part != JenScript.ViewPart.Device) {
	            return;
	        }
	        this.getGridManager().setGridsPlugin(this);
	        this.grids = this.getGridManager().getGrids();
	        this.paintGrids(g2d,this.grids);
	    },
	});

})();<commit_msg>fix defect on grid<commit_after>(function(){

	JenScript.AbstractGridPlugin = function(config) {
		this._init(config);
	};
	JenScript.Model.inheritPrototype(JenScript.AbstractGridPlugin, JenScript.Plugin);
	JenScript.Model.addMethods(JenScript.AbstractGridPlugin, {
		_init : function(config){
			config = config ||{};
			this.grids = [];
			this.sensible = 5;
			config.name = (config.name !== undefined)?config.name : 'AbstractGridPlugin';
			config.priority = -10000;
			this.gridOrientation = config.gridOrientation;
			this.gridColor = config.gridColor;
			var fn = function(g){};
			this.gridWidth =(config.gridWidth !== undefined)?config.gridWidth : 1;
			this.gridOpacity =(config.gridOpacity !== undefined)?config.gridOpacity : 1;
			this.onGridPress = (config.onGridPress !== undefined)?config.onGridPress : fn;
			this.onGridRelease = (config.onGridRelease !== undefined)?config.onGridRelease : fn;
			this.onGridEnter = (config.onGridEnter !== undefined)?config.onGridEnter : fn;
			this.onGridExit = (config.onGridExit !== undefined)?config.onGridExit : fn;
			this.onGrid = (config.onGrid !== undefined)?config.onGrid : fn;

			JenScript.Plugin.call(this,config);
		},

		onProjectionRegister : function(){
			var that = this;
			this.getProjection().addProjectionListener('boundChanged', function(){
				that.repaintPlugin();
			},that.toString());
		},

		onMove : function(evt,part,x,y){
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                var z = (this.gridOrientation === 'Vertical')?x:y;
                if(Math.abs(z - g.deviceValue) < this.sensible && !g.enter){
                	g.enter = true;
                	this.onGridEnter(g);
                	this.onGrid('enter',g);
                }else if(Math.abs(z - g.deviceValue) > this.sensible && g.enter){
                	g.enter = false;
                	this.onGridExit(g);
                	this.onGrid('exit',g);
                }
			}
		},

		onPress : function(evt,part,x,y){
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                if(g.enter){
                    g.press = true;
                	this.onGridPress(g);
                	this.onGrid('press',g);
                }
			}
		},

		onRelease : function(evt,part,x,y){
			for (var i = 0; i < this.grids.length; i++) {
                var g = this.grids[i];
                if(g.press){
                	this.press = false;
                	this.onGridRelease(g);
                	this.onGrid('release',g);
                }
            }
		},

		/**
		 * provides method override to get grids manager that generates grids
		 */
		getGridManager : function(){
			throw new Error('Abstract, grid manager should be supplied.');
		},

		paintGrids : function(g2d,grids) {
			for (var i = 0; i < grids.length; i++) {
                var grid = grids[i];
                var gd = grid.deviceValue;
                var or = this.gridOrientation;
                var color = (this.gridColor !== undefined)?this.gridColor:this.getProjection().themeColor;
                var x1 = (or === 'Vertical')?gd:0;
                var y1 = (or === 'Vertical')?0:gd;
                var x2 = (or === 'Vertical')?gd:this.getProjection().getPixelWidth();
                var y2 = (or === 'Vertical')?this.getProjection().getPixelHeight():gd;
                var gridLine = new JenScript.SVGLine().Id('grid'+JenScript.sequenceId++).from(x1,y1).to(x2,y2).stroke(color).strokeWidth(this.gridWidth).strokeOpacity(this.gridOpacity).fillNone();
                grid.element = gridLine.toSVG();
                g2d.insertSVG(grid.element);
			}
	    },

		paintPlugin : function(g2d,part) {
	        if (part != JenScript.ViewPart.Device) {
	            return;
	        }
	        this.getGridManager().setGridsPlugin(this);
	        this.grids = this.getGridManager().getGrids();
	        this.paintGrids(g2d,this.grids);
	    },
	});

})();<|endoftext|>