<commit_before>// @flow
import React from 'react'
import LoadingView from '../components/loading'
import qs from 'querystring'
import {NoticeView} from '../components/notice'
import type {TopLevelViewPropsType} from '../types'
import {FancyMenu} from './components/fancy-menu'
import type {BonAppMenuInfoType, BonAppCafeInfoType} from './types'
import sample from 'lodash/sample'
import values from 'lodash/values'
import type momentT from 'moment'
import moment from 'moment-timezone'
const CENTRAL_TZ = 'America/Winnipeg'
import {findMenu} from './lib/find-menu'

const bonappMenuBaseUrl = 'http://legacy.cafebonappetit.com/api/2/menus'
const bonappCafeBaseUrl = 'http://legacy.cafebonappetit.com/api/2/cafes'
const fetchJsonQuery = (url, query) => fetchJson(`${url}?${qs.stringify(query)}`)

export class BonAppHostedMenu extends React.Component {
  state: {
    error: ?Error,
    loading: boolean,
    now: momentT,
    cafeInfo: ?BonAppCafeInfoType,
    cafeMenu: ?BonAppMenuInfoType,
  } = {
    error: null,
    loading: true,
    now: moment.tz(CENTRAL_TZ),
    cafeMenu: null,
    cafeInfo: null,
  }

  componentWillMount() {
    this.fetchData()
  }

  props: TopLevelViewPropsType & {
    cafeId: string,
    loadingMessage: string[],
    name: string,
  }

  fetchData = async () => {
    this.setState({loading: true})

    let cafeMenu = null
    let cafeInfo = null

    try {
      let requests = await Promise.all([
        fetchJsonQuery(bonappMenuBaseUrl, {cafe: this.props.cafeId}),
        fetchJsonQuery(bonappCafeBaseUrl, {cafe: this.props.cafeId}),
      ])
      cafeMenu = (requests[0]: BonAppMenuInfoType)
      cafeInfo = (requests[1]: BonAppCafeInfoType)
    } catch (err) {
      this.setState({error: err})
    }

    this.setState({loading: false, cafeMenu, cafeInfo, now: moment.tz(CENTRAL_TZ)})
  }

  findCafeMessage = (cafeId: string, cafeInfo: BonAppCafeInfoType, now: momentT) => {
    let actualCafeInfo = cafeInfo.cafes[cafeId]
    if (!actualCafeInfo) {
      return 'BonApp did not return a menu for that café'
    }

    let today = actualCafeInfo.days.find(({date}) => date === now.format('YYYY-MM-DD'))
    if (!today) {
      return 'Closed today'
    } else if (today.status === 'closed') {
      return today.message || 'Closed today'
    }

    return null
  }

  render() {
    if (this.state.loading) {
      return <LoadingView text={sample(this.props.loadingMessage)} />
    }

    if (this.state.error) {
      return <NoticeView text={'Error: ' + this.state.error.message} />
    }

    if (!this.state.cafeMenu || !this.state.cafeInfo) {
      return <NoticeView text='Something went wrong. Email odt@stolaf.edu to let them know?' />
    }

    let {cafeId} = this.props
    let {now, cafeMenu, cafeInfo} = this.state

    // We grab the "today" info from here because BonApp returns special
    // messages in this response, like "Closed for Christmas Break"
    let specialMessage = this.findCafeMessage(cafeId, cafeInfo, now)
    if (specialMessage) {
      return <NoticeView text={specialMessage} />
    }

    // We hard-code to the first day returned because we're only requesting one day.
    // `cafes` is a map of cafe ids to cafes, but we only request one at a time.
    let dayparts = cafeMenu.days[0].cafes[cafeId].dayparts
    let mealInfo = findMenu(dayparts, now)
    let mealName = mealInfo ? mealInfo.label : ''
    let stationMenus = mealInfo ? mealInfo.stations : []

    return (
      <FancyMenu
        route={this.props.route}
        navigator={this.props.navigator}
        foodItems={values(cafeMenu.items)}
        menuCorIcons={cafeMenu.cor_icons}
        menuLabel={mealName}
        now={now}
        name={this.props.name}
        stationMenus={stationMenus}
      />
    )
  }
}
<commit_msg>re-fetch BonApp data when props change<commit_after>// @flow
import React from 'react'
import LoadingView from '../components/loading'
import qs from 'querystring'
import {NoticeView} from '../components/notice'
import type {TopLevelViewPropsType} from '../types'
import {FancyMenu} from './components/fancy-menu'
import type {BonAppMenuInfoType, BonAppCafeInfoType} from './types'
import sample from 'lodash/sample'
import values from 'lodash/values'
import type momentT from 'moment'
import moment from 'moment-timezone'
const CENTRAL_TZ = 'America/Winnipeg'
import {findMenu} from './lib/find-menu'

const bonappMenuBaseUrl = 'http://legacy.cafebonappetit.com/api/2/menus'
const bonappCafeBaseUrl = 'http://legacy.cafebonappetit.com/api/2/cafes'
const fetchJsonQuery = (url, query) => fetchJson(`${url}?${qs.stringify(query)}`)

type BonAppPropsType = TopLevelViewPropsType & {
  cafeId: string,
  loadingMessage: string[],
  name: string,
};

export class BonAppHostedMenu extends React.Component {
  state: {
    error: ?Error,
    loading: boolean,
    now: momentT,
    cafeInfo: ?BonAppCafeInfoType,
    cafeMenu: ?BonAppMenuInfoType,
  } = {
    error: null,
    loading: true,
    now: moment.tz(CENTRAL_TZ),
    cafeMenu: null,
    cafeInfo: null,
  }

  componentWillMount() {
    this.fetchData(this.props)
  }

  componentWillReceiveProps(newProps: BonAppPropsType) {
    this.props.cafeId !== newProps.cafeId && this.fetchData(newProps)
  }

  props: BonAppPropsType;

  fetchData = async (props: BonAppPropsType) => {
    this.setState({loading: true})

    let cafeMenu = null
    let cafeInfo = null

    try {
      let requests = await Promise.all([
        fetchJsonQuery(bonappMenuBaseUrl, {cafe: props.cafeId}),
        fetchJsonQuery(bonappCafeBaseUrl, {cafe: props.cafeId}),
      ])
      cafeMenu = (requests[0]: BonAppMenuInfoType)
      cafeInfo = (requests[1]: BonAppCafeInfoType)
    } catch (err) {
      this.setState({error: err})
    }

    this.setState({loading: false, cafeMenu, cafeInfo, now: moment.tz(CENTRAL_TZ)})
  }

  findCafeMessage = (cafeId: string, cafeInfo: BonAppCafeInfoType, now: momentT) => {
    let actualCafeInfo = cafeInfo.cafes[cafeId]
    if (!actualCafeInfo) {
      return 'BonApp did not return a menu for that café'
    }

    let today = actualCafeInfo.days.find(({date}) => date === now.format('YYYY-MM-DD'))
    if (!today) {
      return 'Closed today'
    } else if (today.status === 'closed') {
      return today.message || 'Closed today'
    }

    return null
  }

  render() {
    if (this.state.loading) {
      return <LoadingView text={sample(this.props.loadingMessage)} />
    }

    if (this.state.error) {
      return <NoticeView text={'Error: ' + this.state.error.message} />
    }

    if (!this.state.cafeMenu || !this.state.cafeInfo) {
      return <NoticeView text='Something went wrong. Email odt@stolaf.edu to let them know?' />
    }

    let {cafeId} = this.props
    let {now, cafeMenu, cafeInfo} = this.state

    // We grab the "today" info from here because BonApp returns special
    // messages in this response, like "Closed for Christmas Break"
    let specialMessage = this.findCafeMessage(cafeId, cafeInfo, now)
    if (specialMessage) {
      return <NoticeView text={specialMessage} />
    }

    // We hard-code to the first day returned because we're only requesting one day.
    // `cafes` is a map of cafe ids to cafes, but we only request one at a time.
    let dayparts = cafeMenu.days[0].cafes[cafeId].dayparts
    let mealInfo = findMenu(dayparts, now)
    let mealName = mealInfo ? mealInfo.label : ''
    let stationMenus = mealInfo ? mealInfo.stations : []

    return (
      <FancyMenu
        route={this.props.route}
        navigator={this.props.navigator}
        foodItems={values(cafeMenu.items)}
        menuCorIcons={cafeMenu.cor_icons}
        menuLabel={mealName}
        now={now}
        name={this.props.name}
        stationMenus={stationMenus}
      />
    )
  }
}
<|endoftext|>


<commit_before>(function (root, factory) {
    /* istanbul ignore next */
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else {
        root.Glry = factory();
    }
}(this, function () {
    'use strict';

    function extend(target, source) {
        if (typeof source !== 'object') return target;
        for (var prop in source) {
            target[prop] = source[prop];
        }
        return target;
    }

    function cssPrefix() {
        var s = (document.body || document.documentElement).style;
        if (s.WebkitTransform == '') return '-webkit-';
        return '';
    }

    function cssTranslateX(element, positionX, speed) {
        var options = {},
            prefix = cssPrefix();
        options[prefix + 'transform'] = 'translateX(' + positionX + ')';
        options[prefix + 'transition'] = prefix + 'transform ' + speed + 's linear, opacity ' + speed + 's linear';
        extend(element.style, options);
    }

    function GlryTap(elm) {
        elm.addEventListener('touchstart', this);
        elm.addEventListener('touchmove', this);
        elm.addEventListener('touchend', this);
        elm.addEventListener('touchcancel', this);
        elm.addEventListener('mousedown', this);
        elm.addEventListener('mouseup', this);
    }

    GlryTap.prototype.start = function(e) {
        this.moved = false;
        this.startX = e.clientX || e.touches[0].clientX;
        this.startY = e.clientY || e.touches[0].clientY;
    };

    GlryTap.prototype.move = function(e) {
        if (Math.abs(e.touches[0].clientX - this.startX) > 10 || Math.abs(e.touches[0].clientY - this.startY) > 10) {
            this.moved = true;
        }
    };

    GlryTap.prototype.end = function(e) {
        var tap = new CustomEvent('tap', { bubbles: true, cancelable: true });
        if (!this.moved) {
            e.stopPropagation();
            if (!e.target.dispatchEvent(tap)) {
                e.preventDefault();
            }
        }
    };

    GlryTap.prototype.handleEvent = function (e) {
        switch (e.type) {
            case 'touchstart':  this.start(e);  break;
            case 'touchmove':   this.move(e);   break;
            case 'touchend':    this.end(e);    break;
            case 'touchcancel': this.end(e);    break;
            case 'mousedown':   this.start(e);  break;
            case 'mouseup':     this.end(e);    break;
        }
    };

    function Glry(options) {
        var settings = extend({
                    target: '#figure',
                    animationSpeed: 250,
                    enableKeyboard: true,
                    onLoadStart: false,
                    onLoadEnd: false,
                    load: function () {}
                },
                options),

            elmContainer = typeof settings.target === 'object' ? settings.target : document.querySelector(settings.target),
            elmNavigation = elmContainer.querySelector('.navigation'),
            elmLoading = elmContainer.querySelector('.loading'),
            elmError = elmContainer.querySelector('.error'),
            image = null,
            imageWidth = 0,
            imageHeight = 0,
            swipeDiff = 0,
            inProgress = false;

        window.addEventListener('resize', setImage);
        window.addEventListener('touchmove', preventScrolling);

        toggleVisible();

        if (elmNavigation) {
            var glryTap = new GlryTap(window);
            window.addEventListener('tap', handleNavigationToggle);
            elmNavigation.querySelector('.prev').addEventListener('tap', handleNavigationClick.bind(this, 'left'));
            elmNavigation.querySelector('.next').addEventListener('tap', handleNavigationClick.bind(this, 'right'));
        }

        if (settings.enableKeyboard) {
            window.addEventListener('keydown', handleKeyboard);
        }

        function toggleVisible(elmVisible) {
            [elmLoading, elmError].forEach(function (elm) {
                elm.classList.toggle('hidden', elm !== elmVisible);
            });
        }

        function setImage() {
            if (!image) return true;

            window.scrollTo(0, 0);

            var screenWidth = window.innerWidth,
                screenHeight = window.innerHeight,
                tmpImage = new Image();

            tmpImage.src = image.src;
            tmpImage.onload = function () {
                imageWidth = tmpImage.width;
                imageHeight = tmpImage.height;

                if (imageWidth > screenWidth || imageHeight > screenHeight) {
                    var ratio = imageWidth / imageHeight > screenWidth / screenHeight ? imageWidth / screenWidth : imageHeight / screenHeight;
                    imageWidth /= ratio;
                    imageHeight /= ratio;
                }

                extend(image.style, {
                    'width': imageWidth + 'px',
                    'height': imageHeight + 'px',
                    'top': (window.innerHeight - imageHeight) / 2 + 'px',
                    'left': (window.innerWidth - imageWidth) / 2 + 'px'
                });
            };
        }

        function loadImage(direction) {
            if (inProgress) return false;

            var src = settings.load(direction);
            if (!src) return false;

            direction = direction === 'left' ? 1 : direction === 'right' ? -1 : 0;

            if (image) {
                image.style.opacity = 0;
                cssTranslateX(image, (100 * direction) - swipeDiff + 'px', settings.animationSpeed / 1000);
                setTimeout(removeImage, settings.animationSpeed);
                swipeDiff = 0;
            }

            inProgress = true;
            toggleVisible(elmLoading);
            if (settings.onLoadStart !== false) settings.onLoadStart();

            setTimeout(function () {
                image = document.createElement('img');
                image.src = src;
                image.onload = function () {
                    elmContainer.appendChild(image);
                    setImage();

                    image.style.opacity = 0;
                    cssTranslateX(image, -100 * direction + 'px', 0);
                    setTimeout(function () {
                        image.style.opacity = 1;
                        cssTranslateX(image, 0 + 'px', settings.animationSpeed / 1000);
                    }, 50);

                    setTimeout(function () {
                        inProgress = false;
                        toggleVisible();
                        if (settings.onLoadEnd !== false) settings.onLoadEnd();
                    }, settings.animationSpeed);
                };
                image.onerror = function () {
                    inProgress = false;
                    toggleVisible(elmError);
                    if (settings.onLoadEnd !== false) settings.onLoadEnd();
                };

                var swipeStart = 0,
                    swipeEnd = 0;

                image.addEventListener('touchstart', function (e) {
                    e.preventDefault();
                    swipeStart = e.pageX || e.touches[0].pageX;
                });

                image.addEventListener('touchmove', function (e) {
                    swipeEnd = e.pageX || e.touches[0].pageX;
                    swipeDiff = swipeStart - swipeEnd;
                    cssTranslateX(image, -swipeDiff + 'px', 0);
                });

                image.addEventListener('touchend', function () {
                    if (Math.abs(swipeDiff) > 50) {
                        loadImage(swipeDiff > 0 ? 'right' : 'left');
                    } else {
                        cssTranslateX(image, 0 + 'px', settings.animationSpeed / 1000);
                    }
                });

            }, settings.animationSpeed + 100);
        }

        function removeImage() {
            if (!image || !image.parentNode) return false;
            image.parentNode.removeChild(image);
            image = null;
        }

        function handleKeyboard(e) {
            e.preventDefault();
            var left = [37, 65, 97];
            var right = [39, 68, 100];
            if (left.indexOf(e.keyCode) > -1) {
                loadImage('left');
            } else if (right.indexOf(e.keyCode) > -1) {
                loadImage('right');
            }
        }

        function preventScrolling(e) {
            e.preventDefault();
        }

        function handleNavigationToggle(e) {
            e.preventDefault();
            elmNavigation.style.opacity = Number(elmNavigation.style.opacity) ? 0 : 1;
        }

        function handleNavigationClick(direction, e) {
            e.stopPropagation();
            loadImage(direction);
        }

        loadImage();

        return {
            loadImage: loadImage
        };
    }

    Glry.prototype.extend = extend;

    return Glry;

}));
<commit_msg>Move center logic to a function.<commit_after>(function (root, factory) {
    /* istanbul ignore next */
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else {
        root.Glry = factory();
    }
}(this, function () {
    'use strict';

    function extend(target, source) {
        if (typeof source !== 'object') return target;
        for (var prop in source) {
            target[prop] = source[prop];
        }
        return target;
    }

    function cssPrefix() {
        var s = (document.body || document.documentElement).style;
        if (s.WebkitTransform == '') return '-webkit-';
        return '';
    }

    function cssTranslateX(element, positionX, speed) {
        var options = {},
            prefix = cssPrefix();
        options[prefix + 'transform'] = 'translateX(' + positionX + ')';
        options[prefix + 'transition'] = prefix + 'transform ' + speed + 's linear, opacity ' + speed + 's linear';
        extend(element.style, options);
    }

    function cssCenter(element, width, height) {
        extend(element.style, {
            'width': width + 'px',
            'height': height + 'px',
            'top': (window.innerHeight - height) / 2 + 'px',
            'left': (window.innerWidth - width) / 2 + 'px'
        });
    }

    function GlryTap(elm) {
        elm.addEventListener('touchstart', this);
        elm.addEventListener('touchmove', this);
        elm.addEventListener('touchend', this);
        elm.addEventListener('touchcancel', this);
        elm.addEventListener('mousedown', this);
        elm.addEventListener('mouseup', this);
    }

    GlryTap.prototype.start = function(e) {
        this.moved = false;
        this.startX = e.clientX || e.touches[0].clientX;
        this.startY = e.clientY || e.touches[0].clientY;
    };

    GlryTap.prototype.move = function(e) {
        if (Math.abs(e.touches[0].clientX - this.startX) > 10 || Math.abs(e.touches[0].clientY - this.startY) > 10) {
            this.moved = true;
        }
    };

    GlryTap.prototype.end = function(e) {
        var tap = new CustomEvent('tap', { bubbles: true, cancelable: true });
        if (!this.moved) {
            e.stopPropagation();
            if (!e.target.dispatchEvent(tap)) {
                e.preventDefault();
            }
        }
    };

    GlryTap.prototype.handleEvent = function (e) {
        switch (e.type) {
            case 'touchstart':  this.start(e);  break;
            case 'touchmove':   this.move(e);   break;
            case 'touchend':    this.end(e);    break;
            case 'touchcancel': this.end(e);    break;
            case 'mousedown':   this.start(e);  break;
            case 'mouseup':     this.end(e);    break;
        }
    };

    function Glry(options) {
        var settings = extend({
                    target: '#figure',
                    animationSpeed: 250,
                    enableKeyboard: true,
                    onLoadStart: false,
                    onLoadEnd: false,
                    load: function () {}
                },
                options),

            elmContainer = typeof settings.target === 'object' ? settings.target : document.querySelector(settings.target),
            elmNavigation = elmContainer.querySelector('.navigation'),
            elmLoading = elmContainer.querySelector('.loading'),
            elmError = elmContainer.querySelector('.error'),
            image = null,
            imageWidth = 0,
            imageHeight = 0,
            swipeDiff = 0,
            inProgress = false;

        window.addEventListener('resize', setImage);
        window.addEventListener('touchmove', preventScrolling);

        toggleVisible();

        if (elmNavigation) {
            var glryTap = new GlryTap(window);
            window.addEventListener('tap', handleNavigationToggle);
            elmNavigation.querySelector('.prev').addEventListener('tap', handleNavigationClick.bind(this, 'left'));
            elmNavigation.querySelector('.next').addEventListener('tap', handleNavigationClick.bind(this, 'right'));
        }

        if (settings.enableKeyboard) {
            window.addEventListener('keydown', handleKeyboard);
        }

        function toggleVisible(elmVisible) {
            [elmLoading, elmError].forEach(function (elm) {
                elm.classList.toggle('hidden', elm !== elmVisible);
            });
        }

        function setImage() {
            if (!image) return true;

            window.scrollTo(0, 0);

            var screenWidth = window.innerWidth,
                screenHeight = window.innerHeight,
                tmpImage = new Image();

            tmpImage.src = image.src;
            tmpImage.onload = function () {
                imageWidth = tmpImage.width;
                imageHeight = tmpImage.height;

                if (imageWidth > screenWidth || imageHeight > screenHeight) {
                    var ratio = imageWidth / imageHeight > screenWidth / screenHeight ? imageWidth / screenWidth : imageHeight / screenHeight;
                    imageWidth /= ratio;
                    imageHeight /= ratio;
                }

                cssCenter(image, imageWidth, imageHeight);
            };
        }

        function loadImage(direction) {
            if (inProgress) return false;

            var src = settings.load(direction);
            if (!src) return false;

            direction = direction === 'left' ? 1 : direction === 'right' ? -1 : 0;

            if (image) {
                image.style.opacity = 0;
                cssTranslateX(image, (100 * direction) - swipeDiff + 'px', settings.animationSpeed / 1000);
                setTimeout(removeImage, settings.animationSpeed);
                swipeDiff = 0;
            }

            inProgress = true;
            toggleVisible(elmLoading);
            if (settings.onLoadStart !== false) settings.onLoadStart();

            setTimeout(function () {
                image = document.createElement('img');
                image.src = src;
                image.onload = function () {
                    elmContainer.appendChild(image);
                    setImage();

                    image.style.opacity = 0;
                    cssTranslateX(image, -100 * direction + 'px', 0);
                    setTimeout(function () {
                        image.style.opacity = 1;
                        cssTranslateX(image, 0 + 'px', settings.animationSpeed / 1000);
                    }, 50);

                    setTimeout(function () {
                        inProgress = false;
                        toggleVisible();
                        if (settings.onLoadEnd !== false) settings.onLoadEnd();
                    }, settings.animationSpeed);
                };
                image.onerror = function () {
                    inProgress = false;
                    toggleVisible(elmError);
                    if (settings.onLoadEnd !== false) settings.onLoadEnd();
                };

                var swipeStart = 0,
                    swipeEnd = 0;

                image.addEventListener('touchstart', function (e) {
                    e.preventDefault();
                    swipeStart = e.pageX || e.touches[0].pageX;
                });

                image.addEventListener('touchmove', function (e) {
                    swipeEnd = e.pageX || e.touches[0].pageX;
                    swipeDiff = swipeStart - swipeEnd;
                    cssTranslateX(image, -swipeDiff + 'px', 0);
                });

                image.addEventListener('touchend', function () {
                    if (Math.abs(swipeDiff) > 50) {
                        loadImage(swipeDiff > 0 ? 'right' : 'left');
                    } else {
                        cssTranslateX(image, 0 + 'px', settings.animationSpeed / 1000);
                    }
                });

            }, settings.animationSpeed + 100);
        }

        function removeImage() {
            if (!image || !image.parentNode) return false;
            image.parentNode.removeChild(image);
            image = null;
        }

        function handleKeyboard(e) {
            e.preventDefault();
            var left = [37, 65, 97];
            var right = [39, 68, 100];
            if (left.indexOf(e.keyCode) > -1) {
                loadImage('left');
            } else if (right.indexOf(e.keyCode) > -1) {
                loadImage('right');
            }
        }

        function preventScrolling(e) {
            e.preventDefault();
        }

        function handleNavigationToggle(e) {
            e.preventDefault();
            elmNavigation.style.opacity = Number(elmNavigation.style.opacity) ? 0 : 1;
        }

        function handleNavigationClick(direction, e) {
            e.stopPropagation();
            loadImage(direction);
        }

        loadImage();

        return {
            loadImage: loadImage
        };
    }

    Glry.prototype.extend = extend;

    return Glry;

}));
<|endoftext|>


<commit_before>function (doc) {
    if (doc.doc_type === 'CommCareCase' && (doc.domain === 'gsid')) {

        emit(
            [doc.domain,
            doc.disease,
            doc.test_version,
            doc.country,
            doc.province,
            doc.district,
            doc.clinic,
            doc.sex,
            doc.opened_on,
            doc.diagnosis,
            parseInt(doc.lot_number, 10),
            doc.gps,
            doc.gps_country,
            doc.gps_province,
            doc.gps_district],
            parseInt(doc.age, 10)
        );
    }
}<commit_msg>use case.test_date for reporting date<commit_after>function (doc) {
    if (doc.doc_type === 'CommCareCase' && (doc.domain === 'gsid')) {
        var date = doc.test_date || doc.opened_on;
        emit(
            [doc.domain,
            doc.disease,
            doc.test_version,
            doc.country,
            doc.province,
            doc.district,
            doc.clinic,
            doc.sex,
            date,
            doc.diagnosis,
            parseInt(doc.lot_number, 10),
            doc.gps,
            doc.gps_country,
            doc.gps_province,
            doc.gps_district],
            parseInt(doc.age, 10)
        );
    }
}<|endoftext|>


<commit_before>(function() {
	/**
	 * Load the list of files asynchronously. This uses recursion in
	 * order to create a queue of files that will be loaded serially.
	 * Each layer, starting at the bottom, loads a file and then loads
	 * the layer on top of it. The very top file on the stack will have
	 * zero files to load, so instead it will be the one to call the
	 * callback to notify the caller that all the content is loaded.
	 *
	 * @param {Object} context function to call this method in the context of
	 * @param {Array.<string>} paths array of strings containing relative paths for required locale data files
	 * @param {Array} results empty array in which to place the resulting json when it is loaded from a file
	 * @param {Object} params An object full of parameters that the caller is passing to this function to help load the files
	 * @param {function(Array.<Object>)} callback callback to call when this function is finished attempting
	 * to load all the files that exist and can be loaded
	 */
	function loadFiles(context, paths, results, params, callback) {
		var root = "resources/";
		if (params && typeof(params.root) !== "undefined") {
			root = params.root + '/';
		}
		if (paths.length > 0) {
			var path = paths.shift();
			var ajax = new enyo.Ajax({url: enyo.path.rewrite("$lib/enyo-ilib/ilib/locale/" + path), cacheBust: false});
			//console.log("moondemo2: browser/async: attempting to load lib/enyo-ilib/ilib/locale/" + path);
			var resultFunc = function(inSender, json) {
                // console.log("moondemo2: " + (!inSender.failed && json ? "success" : "failed"));
				results.push(!inSender.failed && (typeof(json) === 'object') ? json : undefined);
				if (paths.length > 0) {
					loadFiles(context, paths, results, params, callback);
				} else {
					// only the bottom item on the stack will call
					// the callback
					callback.call(context, results);
				}
			};
			ajax.response(this, resultFunc);
			ajax.error(this, function(inSender, json) {
				// not there? Try the standard place instead
				var file = root + path;
				// console.log("moondemo2: browser/async: attempting to load " + file);
				var ajax2 = new enyo.Ajax({url: file, cacheBust: false});

				ajax2.response(this, resultFunc);
				ajax2.error(this, resultFunc);
				ajax2.go();
			});
			ajax.go();
		}
	}

	ilib.setLoaderCallback(enyo.bind(this, function(paths, sync, params, callback) {
		if (sync) {
			var ret = [];
			var root = "resources/";
			if (params && typeof(params.root) !== "undefined") {
				root = params.root + '/';
			}
			// synchronous
			paths.forEach(function (path) {
				// console.log("browser/sync: attempting to load lib/enyo-ilib/ilib/locale/" + path);
				var ajax = new enyo.Ajax({
					url: enyo.path.rewrite("$lib/enyo-ilib/ilib/locale/" + path),
					sync: true, cacheBust: false
				});

				var handler = function(inSender, json) {
                    // console.log((!inSender.failed && json ? "success" : "failed"));
					ret.push(!inSender.failed && (typeof(json) === 'object') ? json : undefined);
				};
				ajax.response(this, handler);
				ajax.error(this, function(inSender, json) {
					// console.log("browser/sync: Now attempting to load " + root + path);
					var ajax2 = new enyo.Ajax({
						url: root + path,
						sync: true, cacheBust: false
					});
					ajax2.response(this, handler);
					ajax2.error(this, handler);
					ajax2.go();
				});
				ajax.go();
			});

			if (typeof(callback) === 'function') {
				callback.call(this, ret);
			}
			return ret;
		}

		// asynchronous
		var results = [];
		loadFiles(this, paths, results, params, callback);
	}));

	if (typeof(window.UILocale) !== 'undefined') {
		// this is a hack until GF-1581 is fixed
		ilib.setLocale(window.UILocale);
	}

	// enyo.updateI18NClasses should be called after every setLocale, but there isn't such a callback in current version
    enyo.updateI18NClasses = function updateBodyClasses() {
        var li = new ilib.LocaleInfo(); // for the current locale
        var locale = li.getLocale();
		var base = "enyo-locale-";

        // Remove old style definitions (hack style becouse enyo.dom doesn't have methods like enyo.dom.getBodyClasses, enyo.dom.removeBodyClass)
        if (document && document.body && document.body.className && document.body.className) {
            document.body.className = document.body.className.replace(new RegExp('(^|\\s)'+ base +'[^\\s]*', 'g'), '');
        }

        // We use the non-latin fonts for these languages (even though their scripts are technically considered latin)
        var nonLatinLanguageOverrides = ["bs", "cs", "hr", "hu", "lv", "lt", "pl", "ro", "sr", "sl", "tr", "vi"];
        // We use the latin fonts (with non-Latin fallback) for these languages (even though their scripts are non-latin)
        var latinLanguageOverrides = ["ko"];
		var scriptName = li.getScript();
		if ((scriptName !== "Latn" || enyo.indexOf(locale.getLanguage(), nonLatinLanguageOverrides) !== -1) &&
			(enyo.indexOf(locale.getLanguage(), latinLanguageOverrides) < 0)) {
			// allow enyo to define other fonts for non-Latin languages, or for certain
			// Latin-based languages where the characters with some accents don't appear in the
			// regular fonts, creating a strange "ransom note" look with a mix of fonts in the
			// same word. So, treat it like a non-Latin language in order to get all the characters
			// to display with the same font.
			enyo.dom.addBodyClass(base + "non-latin");
		}
		if (scriptName !== 'Latn' && scriptName !== 'Cyrl' && scriptName !== 'Grek') {
			// GF-45884: allow enyo to avoid setting italic fonts for those scripts that do not
			// commonly use italics
			enyo.dom.addBodyClass(base + "non-italic");
		}

		// allow enyo to apply right-to-left styles to the app and widgets if necessary
		var script = new ilib.ScriptInfo(scriptName);
		if (script.getScriptDirection() === "rtl") {
			enyo.dom.addBodyClass(base + "right-to-left");
			if (enyo.Control) {
				enyo.Control.prototype.rtl = true;
			}
		}

		// allow enyo or the apps to give CSS classes that are specific to the language, country, or script
		if (locale.getLanguage()) {
			enyo.dom.addBodyClass(base + locale.getLanguage());
			if (locale.getScript()) {
				enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getScript());
				if (locale.getRegion()) {
					enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getScript() + "-" + locale.getRegion());
				}
			} else if (locale.getRegion()) {
				enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getRegion());
			}
		}
		if (locale.getScript()) {
			enyo.dom.addBodyClass(base + locale.getScript());
		}
		if (locale.getRegion()) {
			enyo.dom.addBodyClass(base + locale.getRegion());
		}
		// Recreate the case mappers to use the just-recently-set locale
	 	enyo.setCaseMappers();
   };
})();

/*
 * Reset the $L function to use ilib instead of the dummy function that enyo
 * comes with by default.
 */
$L = function (string) {
	var str;
	if (!$L.rb) {
		$L.setLocale();
	}
	if (typeof(string) === 'string') {
		if (!$L.rb) {
			return string;
		}
		str = $L.rb.getString(string);
	} else if (typeof(string) === 'object') {
		if (typeof(string.key) !== 'undefined' && typeof(string.value) !== 'undefined') {
			if (!$L.rb) {
				return string.value;
			}
			str = $L.rb.getString(string.value, string.key);
		} else {
			str = "";
		}
	} else {
		str = string;
	}
	return str.toString();
};

/**
 * Set the locale for the strings that $L loads. This may reload the
 * string resources if necessary.
 * @param {string} spec the locale specifier
 */
$L.setLocale = function (spec) {
	var locale = new ilib.Locale(spec);
	if (!$L.rb || spec !== $L.rb.getLocale().getSpec()) {
		$L.rb = new ilib.ResBundle({
			locale: locale,
			type: "html",
			name: "strings",
			sync: true,
			lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
		});
	}
};

/**
 * Set CaseMapper object references to ilib's current locale (its most recently set, by default)
 */
enyo.setCaseMappers = function() {
	enyo.toLowerCase.mapper = new ilib.CaseMapper({direction: "tolower"});
	enyo.toUpperCase.mapper = new ilib.CaseMapper({direction: "toupper"});
};

/**
 * Override Enyo's toLowerCase and toUpperCase methods with these fancy ones
 * that call iLib's locale-safe case mapper.
 */
enyo.toLowerCase = function(inString) {
	if (typeof(inString) === "undefined" || typeof(inString) === "null") {
		return inString;
	}
	return enyo.toLowerCase.mapper.map(inString);
};
enyo.toUpperCase = function(inString) {
	if (typeof(inString) === "undefined" || typeof(inString) === "null") {
		return inString;
	}
	return enyo.toUpperCase.mapper.map(inString);
};

/**
 * This Enyo hook lets us know that the system locale has changed and gives
 * us a chance to update the iLib locale before Enyo broadcasts its
 * `onlocalechange` signal.
 * Provide an inLocale string, like "en-US" or "ja-JP", to conveniently set
 * that locale immediately. Provide nothing, and reset the locale back to the
 * browser's default language.
 */
enyo.updateLocale = function(inLocale) {
	ilib.setLocale(inLocale || navigator.language);
	$L.setLocale(inLocale || navigator.language);
	enyo.updateI18NClasses();
};

// we go ahead and run this once during loading of iLib settings are valid
// during the loads of later libraries.
enyo.updateLocale();
<commit_msg>Corrected a flaw in input checking logic of toLowerCase and toUpperCase. Enyo-DCO-1.1-Signed-off-by: Blake Stephens <blake.stephens@lge.com><commit_after>(function() {
	/**
	 * Load the list of files asynchronously. This uses recursion in
	 * order to create a queue of files that will be loaded serially.
	 * Each layer, starting at the bottom, loads a file and then loads
	 * the layer on top of it. The very top file on the stack will have
	 * zero files to load, so instead it will be the one to call the
	 * callback to notify the caller that all the content is loaded.
	 *
	 * @param {Object} context function to call this method in the context of
	 * @param {Array.<string>} paths array of strings containing relative paths for required locale data files
	 * @param {Array} results empty array in which to place the resulting json when it is loaded from a file
	 * @param {Object} params An object full of parameters that the caller is passing to this function to help load the files
	 * @param {function(Array.<Object>)} callback callback to call when this function is finished attempting
	 * to load all the files that exist and can be loaded
	 */
	function loadFiles(context, paths, results, params, callback) {
		var root = "resources/";
		if (params && typeof(params.root) !== "undefined") {
			root = params.root + '/';
		}
		if (paths.length > 0) {
			var path = paths.shift();
			var ajax = new enyo.Ajax({url: enyo.path.rewrite("$lib/enyo-ilib/ilib/locale/" + path), cacheBust: false});
			//console.log("moondemo2: browser/async: attempting to load lib/enyo-ilib/ilib/locale/" + path);
			var resultFunc = function(inSender, json) {
                // console.log("moondemo2: " + (!inSender.failed && json ? "success" : "failed"));
				results.push(!inSender.failed && (typeof(json) === 'object') ? json : undefined);
				if (paths.length > 0) {
					loadFiles(context, paths, results, params, callback);
				} else {
					// only the bottom item on the stack will call
					// the callback
					callback.call(context, results);
				}
			};
			ajax.response(this, resultFunc);
			ajax.error(this, function(inSender, json) {
				// not there? Try the standard place instead
				var file = root + path;
				// console.log("moondemo2: browser/async: attempting to load " + file);
				var ajax2 = new enyo.Ajax({url: file, cacheBust: false});

				ajax2.response(this, resultFunc);
				ajax2.error(this, resultFunc);
				ajax2.go();
			});
			ajax.go();
		}
	}

	ilib.setLoaderCallback(enyo.bind(this, function(paths, sync, params, callback) {
		if (sync) {
			var ret = [];
			var root = "resources/";
			if (params && typeof(params.root) !== "undefined") {
				root = params.root + '/';
			}
			// synchronous
			paths.forEach(function (path) {
				// console.log("browser/sync: attempting to load lib/enyo-ilib/ilib/locale/" + path);
				var ajax = new enyo.Ajax({
					url: enyo.path.rewrite("$lib/enyo-ilib/ilib/locale/" + path),
					sync: true, cacheBust: false
				});

				var handler = function(inSender, json) {
                    // console.log((!inSender.failed && json ? "success" : "failed"));
					ret.push(!inSender.failed && (typeof(json) === 'object') ? json : undefined);
				};
				ajax.response(this, handler);
				ajax.error(this, function(inSender, json) {
					// console.log("browser/sync: Now attempting to load " + root + path);
					var ajax2 = new enyo.Ajax({
						url: root + path,
						sync: true, cacheBust: false
					});
					ajax2.response(this, handler);
					ajax2.error(this, handler);
					ajax2.go();
				});
				ajax.go();
			});

			if (typeof(callback) === 'function') {
				callback.call(this, ret);
			}
			return ret;
		}

		// asynchronous
		var results = [];
		loadFiles(this, paths, results, params, callback);
	}));

	if (typeof(window.UILocale) !== 'undefined') {
		// this is a hack until GF-1581 is fixed
		ilib.setLocale(window.UILocale);
	}

	// enyo.updateI18NClasses should be called after every setLocale, but there isn't such a callback in current version
    enyo.updateI18NClasses = function updateBodyClasses() {
        var li = new ilib.LocaleInfo(); // for the current locale
        var locale = li.getLocale();
		var base = "enyo-locale-";

        // Remove old style definitions (hack style becouse enyo.dom doesn't have methods like enyo.dom.getBodyClasses, enyo.dom.removeBodyClass)
        if (document && document.body && document.body.className && document.body.className) {
            document.body.className = document.body.className.replace(new RegExp('(^|\\s)'+ base +'[^\\s]*', 'g'), '');
        }

        // We use the non-latin fonts for these languages (even though their scripts are technically considered latin)
        var nonLatinLanguageOverrides = ["bs", "cs", "hr", "hu", "lv", "lt", "pl", "ro", "sr", "sl", "tr", "vi"];
        // We use the latin fonts (with non-Latin fallback) for these languages (even though their scripts are non-latin)
        var latinLanguageOverrides = ["ko"];
		var scriptName = li.getScript();
		if ((scriptName !== "Latn" || enyo.indexOf(locale.getLanguage(), nonLatinLanguageOverrides) !== -1) &&
			(enyo.indexOf(locale.getLanguage(), latinLanguageOverrides) < 0)) {
			// allow enyo to define other fonts for non-Latin languages, or for certain
			// Latin-based languages where the characters with some accents don't appear in the
			// regular fonts, creating a strange "ransom note" look with a mix of fonts in the
			// same word. So, treat it like a non-Latin language in order to get all the characters
			// to display with the same font.
			enyo.dom.addBodyClass(base + "non-latin");
		}
		if (scriptName !== 'Latn' && scriptName !== 'Cyrl' && scriptName !== 'Grek') {
			// GF-45884: allow enyo to avoid setting italic fonts for those scripts that do not
			// commonly use italics
			enyo.dom.addBodyClass(base + "non-italic");
		}

		// allow enyo to apply right-to-left styles to the app and widgets if necessary
		var script = new ilib.ScriptInfo(scriptName);
		if (script.getScriptDirection() === "rtl") {
			enyo.dom.addBodyClass(base + "right-to-left");
			if (enyo.Control) {
				enyo.Control.prototype.rtl = true;
			}
		}

		// allow enyo or the apps to give CSS classes that are specific to the language, country, or script
		if (locale.getLanguage()) {
			enyo.dom.addBodyClass(base + locale.getLanguage());
			if (locale.getScript()) {
				enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getScript());
				if (locale.getRegion()) {
					enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getScript() + "-" + locale.getRegion());
				}
			} else if (locale.getRegion()) {
				enyo.dom.addBodyClass(base + locale.getLanguage() + "-" + locale.getRegion());
			}
		}
		if (locale.getScript()) {
			enyo.dom.addBodyClass(base + locale.getScript());
		}
		if (locale.getRegion()) {
			enyo.dom.addBodyClass(base + locale.getRegion());
		}
		// Recreate the case mappers to use the just-recently-set locale
	 	enyo.setCaseMappers();
   };
})();

/*
 * Reset the $L function to use ilib instead of the dummy function that enyo
 * comes with by default.
 */
$L = function (string) {
	var str;
	if (!$L.rb) {
		$L.setLocale();
	}
	if (typeof(string) === 'string') {
		if (!$L.rb) {
			return string;
		}
		str = $L.rb.getString(string);
	} else if (typeof(string) === 'object') {
		if (typeof(string.key) !== 'undefined' && typeof(string.value) !== 'undefined') {
			if (!$L.rb) {
				return string.value;
			}
			str = $L.rb.getString(string.value, string.key);
		} else {
			str = "";
		}
	} else {
		str = string;
	}
	return str.toString();
};

/**
 * Set the locale for the strings that $L loads. This may reload the
 * string resources if necessary.
 * @param {string} spec the locale specifier
 */
$L.setLocale = function (spec) {
	var locale = new ilib.Locale(spec);
	if (!$L.rb || spec !== $L.rb.getLocale().getSpec()) {
		$L.rb = new ilib.ResBundle({
			locale: locale,
			type: "html",
			name: "strings",
			sync: true,
			lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
		});
	}
};

/**
 * Set CaseMapper object references to ilib's current locale (its most recently set, by default)
 */
enyo.setCaseMappers = function() {
	enyo.toLowerCase.mapper = new ilib.CaseMapper({direction: "tolower"});
	enyo.toUpperCase.mapper = new ilib.CaseMapper({direction: "toupper"});
};

/**
 * Override Enyo's toLowerCase and toUpperCase methods with these fancy ones
 * that call iLib's locale-safe case mapper.
 */
enyo.toLowerCase = function(inString) {
	if (typeof(inString) === "undefined" || inString === null) {
		return inString;
	}
	return enyo.toLowerCase.mapper.map(inString);
};
enyo.toUpperCase = function(inString) {
	if (typeof(inString) === "undefined" || inString === null) {
		return inString;
	}
	return enyo.toUpperCase.mapper.map(inString);
};

/**
 * This Enyo hook lets us know that the system locale has changed and gives
 * us a chance to update the iLib locale before Enyo broadcasts its
 * `onlocalechange` signal.
 * Provide an inLocale string, like "en-US" or "ja-JP", to conveniently set
 * that locale immediately. Provide nothing, and reset the locale back to the
 * browser's default language.
 */
enyo.updateLocale = function(inLocale) {
	ilib.setLocale(inLocale || navigator.language);
	$L.setLocale(inLocale || navigator.language);
	enyo.updateI18NClasses();
};

// we go ahead and run this once during loading of iLib settings are valid
// during the loads of later libraries.
enyo.updateLocale();
<|endoftext|>


<commit_before>/*
 * JQuery Tabs
 *
 * https://github.com/shoyan/jquery.tabs.js
 */
;(function($) {
  'use strict';

  $.fn.extend({
    tabs: function(options) {
      var options = options || {};

      return this.each(function() {
        var target = $(this).find('a');

        $(this).children().addClass("jquery-tabs");

        target.on('click', function(e) {
          e.preventDefault();
          var $this = $(this),
          tabID = $this.data('target');

          $(tabID).siblings().removeClass('active')
          $(tabID).addClass('active');

          $this.parent('li').siblings().children().removeClass('active');
          $this.addClass('active');
        });
        if(options.active_tab) {
          activate_tab(options.active_tab);
        }
      });
    },
    activate_tab: function(target) {
      activate_tab(target);
    }
  });

  function activate_tab(target) {
    $(".jquery-tabs > [data-target='" + target + "']").trigger("click");
  }
})(jQuery);

<commit_msg>キャメルケースにした<commit_after>/*
 * JQuery Tabs
 *
 * https://github.com/shoyan/jquery.tabs.js
 */
;(function($) {
  'use strict';

  $.fn.extend({
    tabs: function(options) {
      var options = options || {};

      return this.each(function() {
        var target = $(this).find('a');

        $(this).children().addClass("jquery-tabs");

        target.on('click', function(e) {
          e.preventDefault();
          var $this = $(this),
          tabID = $this.data('target');

          $(tabID).siblings().removeClass('active')
          $(tabID).addClass('active');

          $this.parent('li').siblings().children().removeClass('active');
          $this.addClass('active');
        });
        if(options.active_tab) {
          activateTab(options.active_tab);
        }
      });
    },
    activateTab: function(target) {
      activateTab(target);
    }
  });

  function activateTab(target) {
    $(".jquery-tabs > [data-target='" + target + "']").trigger("click");
  }
})(jQuery);

<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';

// Components
import Page from 'components/app/layout/Page';
import Layout from 'components/app/layout/Layout';
import Tabs from 'components/ui/Tabs';
import Title from 'components/ui/Title';

// My RW
import ProfilesTab from 'components/app/myrw/profiles/ProfilesTab';
import DatasetsTab from 'components/app/myrw/datasets/DatasetsTab';
import DashboardsTab from 'components/app/myrw/dashboards/DashboardsTab';
import WidgetsTab from 'components/app/myrw/widgets/WidgetsTab';
import AreasTab from 'components/app/myrw/areas/AreasTab';

// Contants
const MYRW_TABS = [{
  label: 'Profile',
  value: 'profile',
  route: 'myrw',
  params: { tab: 'profile' }
}, {
  label: 'Datasets',
  value: 'datasets',
  route: 'myrw',
  params: { tab: 'datasets' }
}, {
  label: 'Dashboards',
  value: 'dashboards',
  route: 'myrw',
  params: { tab: 'dashboards' }
}, {
  label: 'Widgets',
  value: 'widgets',
  route: 'myrw',
  params: { tab: 'widgets' }
},
{
  label: 'Areas of interest',
  value: 'areas',
  route: 'myrw',
  params: { tab: 'areas' }
}];

class MyRW extends Page {
  constructor(props) {
    super(props);

    const { url } = props;

    this.state = {
      tab: url.query.tab || 'profile',
      subtab: url.query.subtab
    };
  }

  componentWillReceiveProps(nextProps) {
    const { url } = nextProps;

    this.setState({
      tab: url.query.tab || 'profile',
      subtab: url.query.subtab
    });
  }

  render() {
    const { url, user } = this.props;
    const { tab, subtab } = this.state;
    const userName = user && user.name ? user.name.split(' ')[0] : '';
    const title = `Hi ${userName}!`;

    return (
      <Layout
        title="My Resource Watch Edit Profile"
        description="My Resource Watch Edit Profile description"
        url={url}
        user={user}
        pageHeader
      >

                  <Title className="-primary -huge page-header-title" >
                    {title}
                  </Title>
                  <Tabs
                    options={MYRW_TABS}
                    defaultSelected={tab}
                    selected={tab}
                  />

                {tab === 'profile' &&
                  <ProfilesTab tab={tab} subtab={subtab} />
                }

                {tab === 'datasets' &&
                  <DatasetsTab tab={tab} subtab={subtab} />
                }

                {tab === 'dashboards' &&
                  <DashboardsTab tab={tab} subtab={subtab} />
                }

                {tab === 'areas' &&
                  <AreasTab tag={tab} subtab={subtab} />
                }

                {tab === 'widgets' &&
                  <WidgetsTab tab={tab} subtab={subtab} />
                }

      </Layout>
    );
  }
}

MyRW.defaultProps = {
};

MyRW.propTypes = {
  url: PropTypes.object,
  user: PropTypes.object
};

export default withRedux(initStore, null, null)(MyRW);
<commit_msg>minor fix for My RW header<commit_after>import React from 'react';
import PropTypes from 'prop-types';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';

// Components
import Page from 'components/app/layout/Page';
import Layout from 'components/app/layout/Layout';
import Tabs from 'components/ui/Tabs';
import Title from 'components/ui/Title';

// My RW
import ProfilesTab from 'components/app/myrw/profiles/ProfilesTab';
import DatasetsTab from 'components/app/myrw/datasets/DatasetsTab';
import DashboardsTab from 'components/app/myrw/dashboards/DashboardsTab';
import WidgetsTab from 'components/app/myrw/widgets/WidgetsTab';
import AreasTab from 'components/app/myrw/areas/AreasTab';

// Contants
const MYRW_TABS = [{
  label: 'Profile',
  value: 'profile',
  route: 'myrw',
  params: { tab: 'profile' }
}, {
  label: 'Datasets',
  value: 'datasets',
  route: 'myrw',
  params: { tab: 'datasets' }
}, {
  label: 'Dashboards',
  value: 'dashboards',
  route: 'myrw',
  params: { tab: 'dashboards' }
}, {
  label: 'Widgets',
  value: 'widgets',
  route: 'myrw',
  params: { tab: 'widgets' }
},
{
  label: 'Areas of interest',
  value: 'areas',
  route: 'myrw',
  params: { tab: 'areas' }
}];

class MyRW extends Page {
  constructor(props) {
    super(props);

    const { url } = props;

    this.state = {
      tab: url.query.tab || 'profile',
      subtab: url.query.subtab
    };
  }

  componentWillReceiveProps(nextProps) {
    const { url } = nextProps;

    this.setState({
      tab: url.query.tab || 'profile',
      subtab: url.query.subtab
    });
  }

  render() {
    const { url, user } = this.props;
    const { tab, subtab } = this.state;
    const userName = user && user.name ? ` ${user.name.split(' ')[0]}` : '';
    const title = `Hi${userName}!`;

    return (
      <Layout
        title="My Resource Watch Edit Profile"
        description="My Resource Watch Edit Profile description"
        url={url}
        user={user}
        pageHeader
      >

                  <Title className="-primary -huge page-header-title" >
                    {title}
                  </Title>
                  <Tabs
                    options={MYRW_TABS}
                    defaultSelected={tab}
                    selected={tab}
                  />

                {tab === 'profile' &&
                  <ProfilesTab tab={tab} subtab={subtab} />
                }

                {tab === 'datasets' &&
                  <DatasetsTab tab={tab} subtab={subtab} />
                }

                {tab === 'dashboards' &&
                  <DashboardsTab tab={tab} subtab={subtab} />
                }

                {tab === 'areas' &&
                  <AreasTab tag={tab} subtab={subtab} />
                }

                {tab === 'widgets' &&
                  <WidgetsTab tab={tab} subtab={subtab} />
                }

      </Layout>
    );
  }
}

MyRW.defaultProps = {
};

MyRW.propTypes = {
  url: PropTypes.object,
  user: PropTypes.object
};

export default withRedux(initStore, null, null)(MyRW);
<|endoftext|>


<commit_before>/**
 *
 * @constructor
 */
var RcmEventManager = function () {

    /**
     * Always refers to this object unlike the 'this' JS variable;
     *
     * @type {RcmEventManager}
     */
    var me = this;

    var eventsUrl = '/rcm-event-calender/events';

    var categoriesUrl = '/rcm-event-calender/categories';

    var categories = [];

    var currentCategoryId;

    var eventList;

    var categorySelectContainer;

    var warning = '
Note: Changes to events happen ' +
        'immediately and cannot be rolled back.
';

    me.showManager = function(){
        var form = $('

').addClass('simple');
        categorySelectContainer =
            $('
Loading...
');
        eventList =
            $('

');
        form.append(categorySelectContainer);
        form.append('
');
        form.append(eventList);
        form.append('
');
        form.append(warning);
        form.dialog({
            title:'Event Manager',
            modal:true,
            width:620,
            buttons:{
                Cancel:function () {
                    $(this).dialog("close");
                },
                Ok:function () {
                    $(this).dialog("close");
                }
            }
        });

        me.renderCategorySelect(me.renderEventList);
    };

    /**
     *
     * @param {Function} [callback]
     */
    me.renderCategorySelect = function(callback){
        me.getCategories(function(){
            categorySelectContainer.empty();
            categorySelectContainer.addSelect(
                'categoryId',
                'Event Category',
                categories,
                currentCategoryId
            );
            categorySelectContainer.find('select').change(function(){
                me.changeSelectedCategory($(this).val());
            });
            categorySelectContainer.find('p').append(me.buildEditButtons());

            if(typeof(callback)=='function'){
                callback();
            }
        });
    };

    /**
     *
     * @param {Integer} categoryId
     */
    me.changeSelectedCategory = function(categoryId){
        currentCategoryId = categoryId;
        me.renderEventList();
    };

    me.buildEditButtons = function(){
        var buttonCont = $('');

        var deleteCategoryButton = $('<button>Delete Category</button>');
        deleteCategoryButton.click(
            function(){
                me.deleteCategory(currentCategoryId);
            }
        );
        buttonCont.append(' ').append(deleteCategoryButton);

        var createCategoryButton = $('<button>Create Category</button>');
        createCategoryButton.click(
            function(){
                me.createCategory();
            }
        );
        buttonCont.append(' ').append(createCategoryButton);

        var createEventButton = $('<button>Create Event</button>');
        createEventButton.click(
            function(){
                me.createEvent();
            }
        );
        buttonCont.append(' ').append(createEventButton);

        return buttonCont;
    };

    me.renderEventList = function(){
        eventList.html('
Loading...
');
        me.getEvents(
            currentCategoryId,
            function(events){

                if(events.length){
                    eventList.html('
Event Title	Start Date
');
                }else{
                    eventList.html('
No events found in this category.
')
                }

                var tdOpen = '';
                $.each(events,function(){
                    var tr=$('

');
                    tr.append(tdOpen + this.title + '	');
                    tr.append(tdOpen + this.startDate + '	');
                    tr.disableSelection();
                    eventList.append(tr);
                });

                eventList.find('tr').dblclick(function(){
                    me.editEvent($(this).attr('data-eventId'));
                });

                rcmEdit.pluginContextMenu(
                    {
                        selector:'#eventManagerList tr',
                        //Here are the right click menu options
                        items:{
                            deleteEvent:{
                                name:'Delete Event',
                                icon:'delete',
                                callback:function(){
                                    me.deleteEvent(
                                        $(this).attr('data-eventId')
                                    );
                                }
                            },
                            editEvent:{
                                name:'Edit Event',
                                icon:'edit',
                                callback:function(){
                                    me.editEvent(
                                        $(this).attr('data-eventId')
                                    );
                                }
                            }
                        }
                    }
                );

                $('body').trigger('rcmEventManagerRender');
            }
        );
    };

    me.createCategory = function(){
        me.showCategoryPropertiesDialog(
            'Create Category',
            {name:''},
            function(category, okButton){
                $.ajax({
                    url: categoriesUrl,
                    type: 'POST',
                    data: category,
                    success: function() {
                        me.renderCategorySelect();
                        okButton.dialog('close');
                    },
                    error:me.handleAjaxError
                });
            }
        );
    };

    /**
     */
    me.createEvent = function(){
        me.showEventPropertiesDialog(
            'Create Event',
            {
                categoryId:currentCategoryId,
                title:'',
                text:'',
                startDate:me.getToday(),
                endDate:me.getToday(),
                mapAddress:''
            },
            function(event, okButton){
                $.ajax({
                    url: eventsUrl,
                    type: 'POST',
                    data: event,
                    success: function() {
                        me.renderEventList();
                        okButton.dialog('close');
                    },
                    error:me.handleAjaxError
                });
            }
        );
    };

    me.getToday = function(){
        var today = new Date();
        return (today.getMonth()+1) + '/'
            + today.getDate() + '/' + today.getFullYear();
    };

    me.handleAjaxError = function(){
        $().confirm(
            'There was a problem. Please make sure you entered valid values ' +
                'and try again.'
        )
    };

    /**
     *
     * @param {Integer} categoryId
     */
    me.deleteCategory = function(categoryId){
        me.getCategory(
            categoryId,
            function(category){
                var message = 'Delete this category AND ALL EVENTS UNDER' +
                    ' IT?

' + category.name +
                    '

' + warning;
                $().confirm(
                    message,
                    function(){
                        $.ajax({
                            url: categoriesUrl + '/' + categoryId,
                            type: 'DELETE',
                            success: function() {
                                me.renderCategorySelect(me.renderEventList);
                            },
                            error:me.handleAjaxError
                        });
                    }
                );
            }
        )
    };

    /**
     *
     * @param {Integer} eventId
     */
    me.deleteEvent = function(eventId){
        me.getEvent(
            eventId,
            function(event){
                var message = 'Delete this event?

' + event.title +
                    '

' + warning;
                $().confirm(
                    message,
                    function(){
                        $.ajax({
                            url: eventsUrl + '/' + eventId,
                            type: 'DELETE',
                            success: function() {
                                me.renderEventList();
                            },
                            error:me.handleAjaxError
                        });
                    }
                );
            }
        )
    };

    /**
     *
     * @param {Integer} eventId
     */
    me.editEvent = function(eventId){
        me.getEvent(
            eventId,
            function(event){
                me.showEventPropertiesDialog(
                    'Edit Event',
                    event,
                    function(event, okButton){
                        $.ajax({
                            url: eventsUrl + '/' + eventId,
                            type: 'PUT',
                            data: event,
                            success: function() {
                                me.renderEventList();
                                okButton.dialog('close');
                            },
                            error:me.handleAjaxError
                        });
                    }
                );
            }
        );
    };

    me.getEvent = function(eventId, callback){
        $.getJSON(
            eventsUrl + '/' + eventId,
                function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    me.getCategory = function(categoryId, callback){
        $.getJSON(
            categoriesUrl + '/' + categoryId,
                function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    me.getEvents = function(categoryId, callback){
        $.getJSON(
            eventsUrl + '?categoryId=' + categoryId,
            function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    /**
     *
     * @param {String} formTitle
     * @param {Object} [event]
     * @param {Function} okCallback
     */
    me.showEventPropertiesDialog = function(formTitle, event, okCallback){

        var inputs = {
            categoryId:$().dialogIn('select', 'Event Category', categories, event.categoryId),
            title:$().dialogIn('text', 'Title', event.title),
            text:$().dialogIn('richEdit', 'Text', event.text),
            startDate:$().dialogIn('date', 'Start Date', event.startDate),
            endDate:$().dialogIn('date' , 'End Date', event.endDate),
            mapAddress:$().dialogIn('text' , 'Map Address', event.mapAddress)
        };

        var form = $('<form></form>')
            .addClass('simple')
            .appendMulti(inputs)
            .append(warning)
            .dialog({
                title:formTitle,
                modal:true,
                width:620,
                buttons:{
                    Cancel:function () {
                        $(this).dialog("close");
                    },
                    Ok:function () {

                        //Get user-entered data from form
                        event.categoryId = inputs.categoryId.val();
                        event.title = inputs.title.val();
                        event.startDate  = inputs.startDate.val();
                        event.endDate  = inputs.endDate.val();
                        event.mapAddress = inputs.mapAddress.val();
                        event.text  = inputs.text.val();

                        okCallback(event,$(this));
                    }
                }
            }
        );
    };

    /**
     *
     * @param {String} formTitle
     * @param {Object} [category]
     * @param {Function} okCallback
     */
    me.showCategoryPropertiesDialog = function(formTitle, category, okCallback){
        var form = $('<form></form>').addClass('simple');
        form.addInput('name', 'Name', category.name);
        form.append(warning);
        form.dialog({
            title:formTitle,
            modal:true,
            width:620,
            buttons:{
                Cancel:function () {
                    $(this).dialog("close");
                },
                Ok:function () {

                    //Get user-entered data from form
                    category.name= form.find('[name=name]').val();

                    okCallback(category,$(this));
                }
            }
        });
    };

    /**
     * updates category array from server
     * @param {Function} [callback]
     */
    me.getCategories = function(callback){
        $.getJSON(
            '/rcm-event-calender/categories',
            function(result) {
                categories=[];
                $.each(result, function(){
                    categories[this.categoryId]=this.name;
                });

                me.setCurrentCategoryToDefault();

                if(typeof(callback)=='function'){
                    callback(categories);
                }
            }
        );
    };

    me.setCurrentCategoryToDefault = function(){
        //Use for-loop to get first key
        for (var firstCategoryId in categories) {
            currentCategoryId = firstCategoryId;
            if(1==1){//Prevent IDE whining
                break;
            }
        }
    };
};<commit_msg>varouis minor js fixes<commit_after>/**
 *
 * @constructor
 */
var RcmEventManager = function () {

    /**
     * Always refers to this object unlike the 'this' JS variable;
     *
     * @type {RcmEventManager}
     */
    var me = this;

    var eventsUrl = '/rcm-event-calender/events';

    var categoriesUrl = '/rcm-event-calender/categories';

    var categories = [];

    var currentCategoryId;

    var eventList;

    var categorySelectContainer;

    var warning = '
Note: Changes to events happen ' +
        'immediately and cannot be rolled back.
';

    me.showManager = function(){
        var form = $('

').addClass('simple');
        categorySelectContainer =
            $('
Loading...
');
        eventList =
            $('

');
        form.append(categorySelectContainer);
        form.append('
');
        form.append(eventList);
        form.append('
');
        form.append(warning);
        form.dialog({
            title:'Event Manager',
            modal:true,
            width:620,
            buttons:{
                Cancel:function () {
                    $(this).dialog("close");
                },
                Ok:function () {
                    $(this).dialog("close");
                }
            }
        });

        me.renderCategorySelect(me.renderEventList);
    };

    /**
     *
     * @param {Function} [callback]
     */
    me.renderCategorySelect = function(callback){
        me.getCategories(function(){
            categorySelectContainer.empty();
            categorySelectContainer.addSelect(
                'categoryId',
                'Event Category',
                categories,
                currentCategoryId
            );
            categorySelectContainer.find('select').change(function(){
                me.changeSelectedCategory($(this).val());
            });
            categorySelectContainer.find('p').append(me.buildEditButtons());

            if(typeof(callback)=='function'){
                callback();
            }
        });
    };

    /**
     *
     * @param {Integer} categoryId
     */
    me.changeSelectedCategory = function(categoryId){
        currentCategoryId = categoryId;
        me.renderEventList();
    };

    me.buildEditButtons = function(){
        var buttonCont = $('');

        var deleteCategoryButton = $('<button>Delete Category</button>');
        deleteCategoryButton.click(
            function(){
                me.deleteCategory(currentCategoryId);
            }
        );
        buttonCont.append(' ').append(deleteCategoryButton);

        var createCategoryButton = $('<button>Create Category</button>');
        createCategoryButton.click(
            function(){
                me.createCategory();
            }
        );
        buttonCont.append(' ').append(createCategoryButton);

        var createEventButton = $('<button>Create Event</button>');
        createEventButton.click(
            function(){
                me.createEvent();
            }
        );
        buttonCont.append(' ').append(createEventButton);

        return buttonCont;
    };

    me.renderEventList = function(){
        eventList.html('
Loading...
');
        me.getEvents(
            currentCategoryId,
            function(events){

                if(events.length){
                    eventList.html('
Event Title	Start Date
');
                }else{
                    eventList.html('
No events found in this category.
')
                }

                var tdOpen = '';
                $.each(events,function(){
                    var tr=$('

');
                    tr.append(tdOpen + this.title + '	');
                    tr.append(tdOpen + this.startDate + '	');
                    tr.disableSelection();
                    eventList.append(tr);
                });

                eventList.find('tr').dblclick(function(){
                    me.editEvent($(this).attr('data-eventId'));
                });

                rcmEdit.pluginContextMenu(
                    {
                        selector:'#eventManagerList tr',
                        //Here are the right click menu options
                        items:{
                            deleteEvent:{
                                name:'Delete Event',
                                icon:'delete',
                                callback:function(){
                                    me.deleteEvent(
                                        $(this).attr('data-eventId')
                                    );
                                }
                            },
                            editEvent:{
                                name:'Edit Event',
                                icon:'edit',
                                callback:function(){
                                    me.editEvent(
                                        $(this).attr('data-eventId')
                                    );
                                }
                            }
                        }
                    }
                );

                $('body').trigger('rcmEventManagerRender');
            }
        );
    };

    me.createCategory = function(){
        me.showCategoryPropertiesDialog(
            'Create Category',
            {name:''},
            function(category, okButton){
                $.ajax({
                    url: categoriesUrl,
                    type: 'POST',
                    data: category,
                    success: function() {
                        me.renderCategorySelect();
                        okButton.dialog('close');
                    },
                    error:me.handleAjaxError
                });
            }
        );
    };

    /**
     */
    me.createEvent = function(){
        me.showEventPropertiesDialog(
            'Create Event',
            {
                categoryId:currentCategoryId,
                title:'',
                text:'',
                startDate:me.getToday(),
                endDate:me.getToday(),
                mapAddress:''
            },
            function(event, okButton){
                $.ajax({
                    url: eventsUrl,
                    type: 'POST',
                    data: event,
                    success: function() {
                        console.log(1);
                        me.renderEventList();
                        okButton.dialog('close');
                    },
                    error:me.handleAjaxError
                });
            }
        );
    };

    me.getToday = function(){
        var today = new Date();
        return (today.getMonth()+1) + '/'
            + today.getDate() + '/' + today.getFullYear();
    };

    me.handleAjaxError = function(e){
        console.log(e);
        $.confirm(
            'There was a problem. Please make sure you entered valid values ' +
                'and try again.'
        )
    };

    /**
     *
     * @param {Integer} categoryId
     */
    me.deleteCategory = function(categoryId){
        me.getCategory(
            categoryId,
            function(category){
                var message = 'Delete this category AND ALL EVENTS UNDER' +
                    ' IT?

' + category.name +
                    '

' + warning;
                $.confirm(
                    message,
                    function(){
                        $.ajax({
                            url: categoriesUrl + '/' + categoryId,
                            type: 'DELETE',
                            success: function() {
                                me.renderCategorySelect(me.renderEventList);
                            },
                            error:me.handleAjaxError
                        });
                    }
                );
            }
        )
    };

    /**
     *
     * @param {Integer} eventId
     */
    me.deleteEvent = function(eventId){
        me.getEvent(
            eventId,
            function(event){
                var message = 'Delete this event?

' + event.title +
                    '

' + warning;
                $.confirm(
                    message,
                    function(){
                        $.ajax({
                            url: eventsUrl + '/' + eventId,
                            type: 'DELETE',
                            success: function() {
                                me.renderEventList();
                            },
                            error:me.handleAjaxError
                        });
                    }
                );
            }
        )
    };

    /**
     *
     * @param {Integer} eventId
     */
    me.editEvent = function(eventId){
        me.getEvent(
            eventId,
            function(event){
                me.showEventPropertiesDialog(
                    'Edit Event',
                    event,
                    function(event, okButton){
                        me.putEventAjax(eventId, event, okButton);
                    }
                );
            }
        );
    };

    me.putEventAjax = function(eventId, event, okButton){
        $.ajax(
            {
                url: eventsUrl + '/' + eventId,
                type: 'PUT',
                data: event,
                complete: function(xhr) {
                    console.log(xhr.readyState);
                    console.log(xhr.status);
                    if (xhr.readyState == 4 && xhr.status == 204) {
                        me.renderEventList();
                        okButton.dialog('close');
                    } else {
                        me.handleAjaxError(xhr);
                    }
                }
            }
        );
    };

    me.getEvent = function(eventId, callback){
        $.getJSON(
            eventsUrl + '/' + eventId,
                function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    me.getCategory = function(categoryId, callback){
        $.getJSON(
            categoriesUrl + '/' + categoryId,
                function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    me.getEvents = function(categoryId, callback){
        $.getJSON(
            eventsUrl + '?categoryId=' + categoryId,
            function(response) {
                callback(response)
            }
        ).error(me.handleAjaxError);
    };

    /**
     *
     * @param {String} formTitle
     * @param {Object} [event]
     * @param {Function} okCallback
     */
    me.showEventPropertiesDialog = function(formTitle, event, okCallback){

        var inputs = {
            categoryId:$.dialogIn('select', 'Event Category', categories, event.categoryId),
            title:$.dialogIn('text', 'Title', event.title),
            text:$.dialogIn('richEdit', 'Text', event.text),
            startDate:$.dialogIn('date', 'Start Date', event.startDate),
            endDate:$.dialogIn('date' , 'End Date', event.endDate),
            mapAddress:$.dialogIn('text' , 'Map Address', event.mapAddress)
        };

        var form = $('<form></form>')
            .addClass('simple')
            .appendMulti(inputs)
            .append(warning)
            .dialog({
                title:formTitle,
                modal:true,
                width:620,
                buttons:{
                    Cancel:function () {
                        $(this).dialog("close");
                    },
                    Ok:function () {

                        //Get user-entered data from form
                        event.categoryId = inputs.categoryId.val();
                        event.title = inputs.title.val();
                        event.startDate  = inputs.startDate.val();
                        event.endDate  = inputs.endDate.val();
                        event.mapAddress = inputs.mapAddress.val();
                        event.text  = inputs.text.val();

                        okCallback(event,$(this));
                    }
                }
            }
        );
    };

    /**
     *
     * @param {String} formTitle
     * @param {Object} [category]
     * @param {Function} okCallback
     */
    me.showCategoryPropertiesDialog = function(formTitle, category, okCallback){

        var nameInput = $.dialogIn('text', 'Name', category.name);

        var form = $('<form></form>')
            .addClass('simple')
            .append(nameInput)
            .append(warning)
            .dialog({
                title:formTitle,
                modal:true,
                width:620,
                buttons:{
                    Cancel:function () {
                        $(this).dialog("close");
                    },
                    Ok:function () {

                        //Get user-entered data from form
                        category.name= nameInput.val();

                        okCallback(category,$(this));
                    }
                }
            }
        );
    };

    /**
     * updates category array from server
     * @param {Function} [callback]
     */
    me.getCategories = function(callback){
        $.getJSON(
            '/rcm-event-calender/categories',
            function(result) {
                categories=[];
                $.each(result, function(){
                    categories[this.categoryId]=this.name;
                });

                me.setCurrentCategoryToDefault();

                if(typeof(callback)=='function'){
                    callback(categories);
                }
            }
        );
    };

    me.setCurrentCategoryToDefault = function(){
        //Use for-loop to get first key
        for (var firstCategoryId in categories) {
            currentCategoryId = firstCategoryId;
            if(1==1){//Prevent IDE whining
                break;
            }
        }
    };
};<|endoftext|>