<commit_before>import React, { Component } from "react";
import moment from "moment";
import reactMixin from "react-mixin";
import ReactFire from "reactfire";
import classNames from "classnames";

// import Button from "./Button";

class Month extends Component {
  constructor(props) {
    super(props);

    this.state = {
      todos: [],
    };

    this.renderDays = this.renderDays.bind(this);
    this.goToDay = this.goToDay.bind(this);
    this.bindFirebase = this.bindFirebase.bind(this);
  }

  componentWillMount() {
    this.bindFirebase(this.props.firebaseRef, this.props.targetDay, this.props.weekRange);
  }

  componentWillReceiveProps(nextProps) {
    if (
      nextProps.targetDay !== this.props.targetDay
      || nextProps.firebaseRef !== this.props.firebaseRef
      || nextProps.startAt !== this.props.weekRange
    ) {
      this.unbind("todos");
      this.bindFirebase(nextProps.firebaseRef, nextProps.targetDay, nextProps.weekRange);
    }
  }

  bindFirebase(firebaseRef, targetDay, weekRange) {
    // console.log("Start at " + moment(targetDay).subtract(weekRange, "weeks").format("ddd DD MM HH:mm"));
    // console.log("Target is " + moment(targetDay).format("ddd DD MM HH:mm"));
    // console.log("Stop at " + moment(targetDay).add(weekRange+1, "weeks").format("ddd DD MM HH:mm"));

    this.bindAsArray(
      firebaseRef
        .orderByChild("date")
        .startAt(moment(targetDay).subtract(weekRange, "weeks").valueOf())
        .endAt(moment(targetDay).add(weekRange+1, "weeks").valueOf()),
      "todos",
      function(error) {
        console.log("Firebase subscription cancelled:")
        console.log(error);
        this.setState({todos: []})
      }.bind(this)
    );
  }

  renderDays(week, nthWeek) {
    return week.map(function(day, nthDay) {
      let text = "";

      this.state.todos.forEach(function(todo) {
        if (todo.date === day.valueOf()) {
          text = todo.text;
        }
      });

      let month, year, textMarker;

      if (text) {
        let lines = [];
        for (let i = 0; i < (text.length/30); i++) {
          lines.push(i);
        }

        textMarker = (

            {lines.map(function(i) {
              const randomWidth = i+1 === lines.length ? Math.floor(Math.random()*(76-38+1)+38) : Math.floor(Math.random()*(100-85+1)+85);

              return (
                <div
                  key={i}
                  style={{width: `${randomWidth}%`}}
                  className={classNames({
                    "border-top": true,
                  })}
                />
              );
            })}

        );
      }

      if (moment(day).startOf("month").isSame(day)) {
        month = day.format("MMM");
        year = day.format("YYYY");
      }

      return (
        <button
          key={day.valueOf()}
          className={classNames({
            "button size-0-75 flex vertical text-align-left padding-0-5 all-caps overflow-hidden": true,
            "color-bright-6": day.isSame(this.props.today),
          })}
          onClick={this.goToDay}
          data-day={day.valueOf()}
        >

            {day.format("DD")} {month} {year}
            {textMarker}

        </button>
      );
    }.bind(this));
  }

  goToDay(event) {
    if (event.target.dataset.day) {
      this.props.goToDay(moment(+event.target.dataset.day));
    }
  }

  render() {
    const firstOfFocusedWeek = moment(this.props.targetDay).startOf("isoweek");

    let pastWeeks = [];
    for (let i = 1; i < this.props.weekRange+1; i++) {
      pastWeeks.unshift(
        {
          firstDay: moment(firstOfFocusedWeek).subtract(i, "weeks"),
          days: [],
        }
      );
    }

    let focusedWeek = [
      {
        firstDay: firstOfFocusedWeek,
        days: [],
      }
    ];

    let futureWeeks = [];
    for (let i = 1; i < this.props.weekRange+1; i++) {
      futureWeeks.push(
        {
          firstDay: moment(firstOfFocusedWeek).add(i, "weeks"),
          days: [],
        }
      );
    }

    let allWeeks = [];
    allWeeks = allWeeks.concat(pastWeeks, focusedWeek, futureWeeks);

    allWeeks.forEach(function(week){
      for (let i = 0; i < 7; i++) {
        week.days.push(moment(week.firstDay).add(i, "days"));
      }
    });

    const weeks = allWeeks.map(function(week, nthWeek) {
      const isCurrentWeek = (
        moment(this.props.today).isBetween(week.days[0], week.days[6], null, "[]")
      );
      const isFutureWeek = (
        moment(this.props.today).isBefore(week.days[0])
      );

      let number = isCurrentWeek ? 2 : 1;
      if (isFutureWeek) { number = 1; }

      return (
        <div
          key={week.days[0].valueOf()}
          className={classNames({
            "week flex even-children border-2": true,
            [`bg-${number}`]: true,
          })}
        >
          {this.renderDays(week.days, nthWeek)}

      );
    }.bind(this));

    return (

          {weeks}

    );
  }
}

reactMixin(Month.prototype, ReactFire);
export default Month;
<commit_msg>Fade month lines in<commit_after>import React, { Component } from "react";
import moment from "moment";
import reactMixin from "react-mixin";
import ReactFire from "reactfire";
import classNames from "classnames";

// import Button from "./Button";

class Month extends Component {
  constructor(props) {
    super(props);

    this.state = {
      todos: [],
    };

    this.renderDays = this.renderDays.bind(this);
    this.goToDay = this.goToDay.bind(this);
    this.bindFirebase = this.bindFirebase.bind(this);
  }

  componentWillMount() {
    this.bindFirebase(this.props.firebaseRef, this.props.targetDay, this.props.weekRange);
  }

  componentWillReceiveProps(nextProps) {
    if (
      nextProps.targetDay !== this.props.targetDay
      || nextProps.firebaseRef !== this.props.firebaseRef
      || nextProps.startAt !== this.props.weekRange
    ) {
      this.unbind("todos");
      this.bindFirebase(nextProps.firebaseRef, nextProps.targetDay, nextProps.weekRange);
    }
  }

  bindFirebase(firebaseRef, targetDay, weekRange) {
    // console.log("Start at " + moment(targetDay).subtract(weekRange, "weeks").format("ddd DD MM HH:mm"));
    // console.log("Target is " + moment(targetDay).format("ddd DD MM HH:mm"));
    // console.log("Stop at " + moment(targetDay).add(weekRange+1, "weeks").format("ddd DD MM HH:mm"));

    this.bindAsArray(
      firebaseRef
        .orderByChild("date")
        .startAt(moment(targetDay).subtract(weekRange, "weeks").valueOf())
        .endAt(moment(targetDay).add(weekRange+1, "weeks").valueOf()),
      "todos",
      function(error) {
        console.log("Firebase subscription cancelled:")
        console.log(error);
        this.setState({todos: []})
      }.bind(this)
    );
  }

  renderDays(week, nthWeek) {
    return week.map(function(day, nthDay) {
      let text = "";

      this.state.todos.forEach(function(todo) {
        if (todo.date === day.valueOf()) {
          text = todo.text;
        }
      });

      let month, year, textMarker;

      if (text) {
        let lines = [];
        for (let i = 0; i < (text.length/30); i++) {
          lines.push(i);
        }

        textMarker = (

            {lines.map(function(i) {
              const randomWidth = i+1 === lines.length ? Math.floor(Math.random()*(76-38+1)+38) : Math.floor(Math.random()*(100-85+1)+85);

              return (
                <div
                  key={i}
                  style={{width: `${randomWidth}%`}}
                  className={classNames({
                    "border-top": true,
                  })}
                />
              );
            })}

        );
      }

      if (moment(day).startOf("month").isSame(day)) {
        month = day.format("MMM");
        year = day.format("YYYY");
      }

      return (
        <button
          key={day.valueOf()}
          className={classNames({
            "button size-0-75 flex vertical text-align-left padding-0-5 all-caps overflow-hidden": true,
            "color-bright-6": day.isSame(this.props.today),
          })}
          onClick={this.goToDay}
          data-day={day.valueOf()}
        >

            {day.format("DD")} {month} {year}
            {textMarker}

        </button>
      );
    }.bind(this));
  }

  goToDay(event) {
    if (event.target.dataset.day) {
      this.props.goToDay(moment(+event.target.dataset.day));
    }
  }

  render() {
    const firstOfFocusedWeek = moment(this.props.targetDay).startOf("isoweek");

    let pastWeeks = [];
    for (let i = 1; i < this.props.weekRange+1; i++) {
      pastWeeks.unshift(
        {
          firstDay: moment(firstOfFocusedWeek).subtract(i, "weeks"),
          days: [],
        }
      );
    }

    let focusedWeek = [
      {
        firstDay: firstOfFocusedWeek,
        days: [],
      }
    ];

    let futureWeeks = [];
    for (let i = 1; i < this.props.weekRange+1; i++) {
      futureWeeks.push(
        {
          firstDay: moment(firstOfFocusedWeek).add(i, "weeks"),
          days: [],
        }
      );
    }

    let allWeeks = [];
    allWeeks = allWeeks.concat(pastWeeks, focusedWeek, futureWeeks);

    allWeeks.forEach(function(week){
      for (let i = 0; i < 7; i++) {
        week.days.push(moment(week.firstDay).add(i, "days"));
      }
    });

    const weeks = allWeeks.map(function(week, nthWeek) {
      const isCurrentWeek = (
        moment(this.props.today).isBetween(week.days[0], week.days[6], null, "[]")
      );
      const isFutureWeek = (
        moment(this.props.today).isBefore(week.days[0])
      );

      let number = isCurrentWeek ? 2 : 1;
      if (isFutureWeek) { number = 1; }

      return (
        <div
          key={week.days[0].valueOf()}
          className={classNames({
            "week flex even-children border-2": true,
            [`bg-${number}`]: true,
          })}
        >
          {this.renderDays(week.days, nthWeek)}

      );
    }.bind(this));

    return (

          {weeks}

    );
  }
}

reactMixin(Month.prototype, ReactFire);
export default Month;
<|endoftext|>


<commit_before>'use strict';

module.exports = function (app) {
  // Root routing
  var core = require('../controllers/core.server.controller');

  // Define error pages
  app.route('/server-error').get(core.renderServerError);

  // Return a 404 for all undefined api, module or lib routes
  app.route('/:url(api|modules|lib)/*').get(core.renderNotFound);

  // Define application route
  app.route('/*').get(core.renderIndex);
};
<commit_msg>Fix: Broken google links<commit_after>'use strict';

module.exports = function (app) {
  // Root routing
  var core = require('../controllers/core.server.controller');

  // Define error pages
  app.route('/server-error').get(core.renderServerError);

  // Return a 404 for all undefined api, module or lib routes
  app.route('/:url(api|modules|lib)/*').get(core.renderNotFound);

  app.route ('/home').get(function (req, res) {
	res.set ('location', 'https://bcdevexchange.org');
	res.status(301).send();
  });
  app.route ('/developers').get(function (req, res) {
	res.set ('location', 'https://bcdevexchange.org/about');
	res.status(301).send();
  });

  // Define application route
  app.route('/*').get(core.renderIndex);

};
<|endoftext|>


<commit_before>import uniqBy from 'lodash/uniqBy'
import filter from 'lodash/filter'
import flatMap from 'lodash/flatMap'

export function getActiveCourses(student) {
	const activeSchedules = filter(student.schedules, s => s.active === true)
	let courses = flatMap(activeSchedules, s => s.courses)
	courses = uniqBy(courses.filter(c => c), course => course.clbid)

	return courses
}
<commit_msg>clean up more types in getActiveCourses<commit_after>// @flow

import uniqBy from 'lodash/uniqBy'
import flatMap from 'lodash/flatMap'
import type {StudentType} from './student'

export function getActiveCourses(student: StudentType) {
	const activeSchedules = student.schedules.filter(s => s.active === true)

	let courses = flatMap(activeSchedules, s => s.courses)
	courses = uniqBy(courses.filter(c => c), course => course.clbid)

	return courses
}
<|endoftext|>


<commit_before>import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { createReactNavigationReduxMiddleware } from 'react-navigation-redux-helpers';
import reducers from './reducers';

// Create middleware and connect
const appNavigatorMiddleware = createReactNavigationReduxMiddleware(state => state.nav, 'root');

const persistConfig = {
  keyPrefix: '',
  key: 'root',
  storage: AsyncStorage,
  blacklist: [
    'nav',
    'pages',
    'user',
    'prescription',
    'patient',
    'form',
    'prescriber',
    'wizard',
    'payment',
    'insurance',
    'dashboard',
    'dispensary',
  ],
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = createStore(persistedReducer, {}, applyMiddleware(thunk, appNavigatorMiddleware));

const persistedStore = persistStore(store);

export { store, persistedStore };
<commit_msg>Add modules to redux blacklist<commit_after>import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { createReactNavigationReduxMiddleware } from 'react-navigation-redux-helpers';
import reducers from './reducers';

// Create middleware and connect
const appNavigatorMiddleware = createReactNavigationReduxMiddleware(state => state.nav, 'root');

const persistConfig = {
  keyPrefix: '',
  key: 'root',
  storage: AsyncStorage,
  blacklist: [
    'nav',
    'pages',
    'user',
    'prescription',
    'patient',
    'form',
    'prescriber',
    'wizard',
    'payment',
    'insurance',
    'dashboard',
    'dispensary',
    'modules',
  ],
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = createStore(persistedReducer, {}, applyMiddleware(thunk, appNavigatorMiddleware));

const persistedStore = persistStore(store);

export { store, persistedStore };
<|endoftext|>


<commit_before>"use strict";

var $ = require('jquery'),
    Bacon = require('baconjs'),
    _ = require('lodash'),
    moment = require("moment"),
    isTypeaheadHiddenField = require('treemap/fieldHelpers'),
    FH = require('treemap/fieldHelpers');

var DATETIME_FORMAT = FH.DATETIME_FORMAT;

var isCombinator = function(pred) {
    return _.isArray(pred) && (pred[0] === "OR" || pred[0] === "AND");
};

var textToBool = function(text) {
    return _.isString(text) && text.toLowerCase() === "true";
};

var boolToText = function(bool) {
    return bool ? "true" : "false";
};

exports.buildElems = function (inputSelector) {
    var build = function build(typeAttr, el) {
        var $el = $(el),
            name = $el.attr('name') || $el.attr('data-search-identifier'),
            type = $el.attr(typeAttr),
            id = $el.attr('id'),
            buildSecondary = _.partial(build, 'data-search-secondary-type'),
            $subElems,
            children = {};

        if (type === "IN") {
            // Exclude further IN types to prevent infinite recursion
            $subElems = $('[data-search-secondary-type]:checkbox')
                .not('[data-search-secondary-type="IN"]');
            children = _.object(_.map($subElems, buildSecondary));
        }

        return[id, {
            'key': name,
            'pred': type,
            'children': children
        }];
    },
    buildPrimary = _.partial(build, 'data-search-type');

    return _.object(_.map($(inputSelector), buildPrimary));
};

function executeSearch(config, search_query) {
    var search = $.ajax({
        url: config.instance.url + 'benefit/search',
        data: {'q': search_query && Object.keys(search_query).length > 0 ?
                JSON.stringify(search_query) :
                ''},
        type: 'GET',
        dataType: 'html'
    });

    return Bacon.fromPromise(search);
}

function updateSearchResults(newMarkup) {
    var $new = $(newMarkup),
        countsMarkup = $new.filter('#tree-and-planting-site-counts').html(),
        benefitsMarkup = $new.filter('#benefit-values').html();
    $('#tree-and-planting-site-counts').html(countsMarkup);
    $('#benefit-values').html(benefitsMarkup);
}

function applySearchToInContainer($container, keyAndPred, search) {
    var searchPreds = search[keyAndPred.key],
        items = searchPreds ? searchPreds.IN : undefined,
        $checks = $container.find('[data-search-in]:checkbox');

    if (_.isArray(items)) {
        // If no elements are checked the list is [null] to be valid SQL
        items = _.reject(items, _.isNull);
        $checks.prop('checked', false);
        _.each(items, function(item) {
            $checks.filter('[data-search-in="' + item + '"]').prop('checked', true);
        });
    } else {
        // The lack of any filter for this IN clause means everything is checked
        $checks.prop('checked', true);
    }

    var preds = _(keyAndPred.children)
        .values()
        .uniq(JSON.stringify)
        .value();

    _.each(preds, function(keyAndPred) {
        var preds = search[keyAndPred.key],
            predValue = preds ? preds[keyAndPred.pred] : undefined,
            $predElems = $checks
                .filter('[name="' + keyAndPred.key + '"]')
                .filter('[data-search-secondary-type="' + keyAndPred.pred +'"]');

        if ( ! _.isUndefined(predValue)) {
            $predElems.prop('checked', false);
            $predElems
                .filter('[value="' + boolToText(predValue) + '"]')
                .prop('checked', true);
        }
    });
}

// Exported for testing
exports._applySearchToInContainer = applySearchToInContainer;

function applySearchToDom(elems, search) {
    _.each(elems, function(keyAndPred, id) {
        var $domElem = $(document.getElementById(id));
        var pred = search[keyAndPred.key];
        var value;

        if (pred && keyAndPred.pred === 'IN') {
            applySearchToInContainer($domElem, keyAndPred, search);
            return;
        }

        if (isCombinator(pred)) {
            value = pred ? pred[1][keyAndPred.pred] : null;
        } else {
            value = pred ? pred[keyAndPred.pred] : null;
        }

        if ($domElem.is('[type="hidden"]')) {
            $domElem.trigger('restore', value);
        } else if ($domElem.is('[data-date-format]')) {
            FH.applyDateToDatepicker($domElem, value);
        } else if($domElem.is(':checkbox')) {
            $domElem.prop('checked', boolToText(value) === $domElem.val());
        } else if ($domElem.is('input')) {
            $domElem.val(value || '');
        }
    });
}

exports.applySearchToDom = applySearchToDom;

exports.reset = function (elems) {
    applySearchToDom(elems, {});
};

exports.buildSearch = function (elems) {
    var buildQueryFromPred = function(identifier, pred) {
            var query = {};
            if ( ! _.isEmpty(pred)) {
                query[identifier] = pred;
            }
            return query;
        },

        buildQueryFromIn = function(id, keyAndPred) {
            var $elem = $(document.getElementById(id)),
                $checks = $elem.find('[data-search-in]:checkbox'),
                pred = {},
                inList;

            // If all elems are checked, don't add the IN predicate
            if ($checks.filter(':not(:checked)').length !== 0) {
                inList = _.map($checks.filter(':checked'), function(check) {
                    return $(check).attr('data-search-in');
                });
                inList = _.uniq(inList);
                // An empty IN clause is invalid SQL, so we need a dummy value
                pred[keyAndPred.pred] = inList.length !== 0 ? inList : [null];
            }
            return buildQueryFromPred(keyAndPred.key, pred);
        },

        buildQuery = function (key_and_pred, id) {
            var $elem = $(document.getElementById(id)),
                val = $elem.val(),
                key = key_and_pred.key,
                pred = {},
                query = {};

            if ($elem.is(':checked') || ($elem.is(':not(:checkbox)') && val && val.length > 0)) {
                if ($elem.is('[data-date-format]')) {
                    var date = moment($elem.datepicker('getDate'));
                    if (key_and_pred.pred === "MIN") {
                        date = date.startOf("day");
                    } else if (key_and_pred.pred === "MAX") {
                        date = date.endOf("day");
                    }
                    val = date.format(DATETIME_FORMAT);
                }

                if ($elem.is(':checkbox')) {
                    if ($elem.is(':checked')) {
                        pred[key_and_pred.pred] = textToBool(val);
                    }
                } else {
                    pred[key_and_pred.pred] = val;
                }
            }
            return buildQueryFromPred(key_and_pred.key, pred);
        };

    return _.reduce(elems, function (preds, key_and_pred, id) {
        var query = {},
            pred = {},
            childPreds,
            getKey = _.compose(_.first, Object.keys);

        if (key_and_pred.pred === 'IN') {
            query = buildQueryFromIn(id, key_and_pred);

            // Add the IN's children to the preds as well
            var allPreds = _(key_and_pred.children)
                .map(buildQuery)
                .reject(_.isEmpty)
                .value();

            _(allPreds)
                .groupBy(getKey)
                .each(function(childPreds, identifier) {
                    // groupBy leaves the elements unchanged, so we need to
                    // pluck out the inner objects, to get a list of {pred: value}
                    var identifierPreds = _.pluck(childPreds, identifier),

                        // If there are any contradictory predicates remove them
                        // (i.e. if there are two predicates of the same type with the same key)
                        //
                        // For example, if there are filters for {ISNULL: false} as
                        // well as {ISNULL: true}, we shouldn't add either to the
                        // query, as when searching for both plots with and without trees
                        unduplicatedKeys = _(identifierPreds)
                            .map(getKey)
                            .countBy()
                            .omit(function(number) {
                                return number > 1;
                            })
                            .keys()
                            .value(),

                        // identifierPred is a single object with all {pred: value}s
                        // merged, for all preds which only occurred once
                        identifierPred = _.pick(_.merge.apply(_, identifierPreds), unduplicatedKeys),

                        childQuery = buildQueryFromPred(identifier, identifierPred);

                    $.extend(true, preds, childQuery);
                });
        } else {
            query = buildQuery(key_and_pred, id);
        }

        // We do a deep extend so that if a predicate field
        // (such as tree.diameter) is already specified,
        // we merge the resulting dicts
        $.extend(true, preds, query);

        return preds;
    }, {});
};

// Arguments
//
// searchStream: a Bacon.js EventStream. The value
//   of the item should be JSON generated from buildSearch
//
// applyFilter: Function to call when filter changes.
exports.init = function(searchStream, config, applyFilter) {
    searchStream.onValue(applyFilter);

    // Clear any previous search results
    searchStream.map('').onValue($('#search-results'), 'html');

    searchStream
        .flatMap(_.partial(executeSearch, config))
        .onValue(updateSearchResults);
};
<commit_msg>Rip out broken display filter code<commit_after>"use strict";

var $ = require('jquery'),
    Bacon = require('baconjs'),
    _ = require('lodash'),
    moment = require("moment"),
    isTypeaheadHiddenField = require('treemap/fieldHelpers'),
    FH = require('treemap/fieldHelpers');

var DATETIME_FORMAT = FH.DATETIME_FORMAT;

var isCombinator = function(pred) {
    return _.isArray(pred) && (pred[0] === "OR" || pred[0] === "AND");
};

var textToBool = function(text) {
    return _.isString(text) && text.toLowerCase() === "true";
};

var boolToText = function(bool) {
    return bool ? "true" : "false";
};

exports.buildElems = function (inputSelector) {
    return _.object(_.map($(inputSelector), function (typeAttr, el) {
        var $el = $(el),
            name = $el.attr('name'),
            type = $el.attr(typeAttr),
            id = $el.attr('id');

        return[id, {
            'key': name,
            'pred': type,
        }];
    }));
};

function executeSearch(config, search_query) {
    var search = $.ajax({
        url: config.instance.url + 'benefit/search',
        data: {'q': search_query && Object.keys(search_query).length > 0 ?
                JSON.stringify(search_query) :
                ''},
        type: 'GET',
        dataType: 'html'
    });

    return Bacon.fromPromise(search);
}

function updateSearchResults(newMarkup) {
    var $new = $(newMarkup),
        countsMarkup = $new.filter('#tree-and-planting-site-counts').html(),
        benefitsMarkup = $new.filter('#benefit-values').html();
    $('#tree-and-planting-site-counts').html(countsMarkup);
    $('#benefit-values').html(benefitsMarkup);
}

function applySearchToDom(elems, search) {
    _.each(elems, function(keyAndPred, id) {
        var $domElem = $(document.getElementById(id));
        var pred = search[keyAndPred.key];
        var value;

        if (isCombinator(pred)) {
            value = pred ? pred[1][keyAndPred.pred] : null;
        } else {
            value = pred ? pred[keyAndPred.pred] : null;
        }

        if ($domElem.is('[type="hidden"]')) {
            $domElem.trigger('restore', value);
        } else if ($domElem.is('[data-date-format]')) {
            FH.applyDateToDatepicker($domElem, value);
        } else if($domElem.is(':checkbox')) {
            $domElem.prop('checked', boolToText(value) === $domElem.val());
        } else if ($domElem.is('input')) {
            $domElem.val(value || '');
        }
    });
}

exports.applySearchToDom = applySearchToDom;

exports.reset = function (elems) {
    applySearchToDom(elems, {});
};

exports.buildSearch = function (elems) {
    return _.reduce(elems, function(preds, key_and_pred, id) {
        var $elem = $(document.getElementById(id)),
            val = $elem.val(),
            key = key_and_pred.key,
            pred = {},
            query = {};

        if ($elem.is(':checked') || ($elem.is(':not(:checkbox)') && val && val.length > 0)) {
            if ($elem.is('[data-date-format]')) {
                var date = moment($elem.datepicker('getDate'));
                if (key_and_pred.pred === "MIN") {
                    date = date.startOf("day");
                } else if (key_and_pred.pred === "MAX") {
                    date = date.endOf("day");
                }
                val = date.format(DATETIME_FORMAT);
            }

            if ($elem.is(":checkbox")) {
                if ($elem.is(":checked")) {
                    pred[key_and_pred.pred] = val;
                }
            } else {
                pred[key_and_pred.pred] = val;
            }

            // We do a deep extend so that if a predicate field
            // (such as tree.diameter) is already specified,
            // we merge the resulting dicts
            query[key] = pred;
            $.extend(true, preds, query);
        }

        return preds;
    }, {});
};

// Arguments
//
// searchStream: a Bacon.js EventStream. The value
//   of the item should be JSON generated from buildSearch
//
// applyFilter: Function to call when filter changes.
exports.init = function(searchStream, config, applyFilter) {
    searchStream.onValue(applyFilter);

    // Clear any previous search results
    searchStream.map('').onValue($('#search-results'), 'html');

    searchStream
        .flatMap(_.partial(executeSearch, config))
        .onValue(updateSearchResults);
};
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var stylesInDom = {},
	memoize = function(fn) {
		var memo;
		return function () {
			if (typeof memo === "undefined") memo = fn.apply(this, arguments);
			return memo;
		};
	},
	isIE9 = memoize(function() {
		return /msie 9\b/.test(window.navigator.userAgent.toLowerCase());
	}),
	getHeadElement = memoize(function () {
		return document.head || document.getElementsByTagName("head")[0];
	}),
	singletonElement = null,
	singletonCounter = 0;

module.exports = function(list, options) {
	if(typeof DEBUG !== "undefined" && DEBUG) {
		if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};
	// Force single-tag solution on IE9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (typeof options.singleton === "undefined") options.singleton = isIE9();

	var styles = listToStyles(list);
	addStylesToDom(styles, options);

	return function update(newList) {
		var mayRemove = [];
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			domStyle.refs--;
			mayRemove.push(domStyle);
		}
		if(newList) {
			var newStyles = listToStyles(newList);
			addStylesToDom(newStyles, options);
		}
		for(var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];
			if(domStyle.refs === 0) {
				for(var j = 0; j < domStyle.parts.length; j++)
					domStyle.parts[j]();
				delete stylesInDom[domStyle.id];
			}
		}
	};
}

function addStylesToDom(styles, options) {
	for(var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];
		if(domStyle) {
			domStyle.refs++;
			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}
			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];
			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}
			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles(list) {
	var styles = [];
	var newStyles = {};
	for(var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};
		if(!newStyles[id])
			styles.push(newStyles[id] = {id: id, parts: [part]});
		else
			newStyles[id].parts.push(part);
	}
	return styles;
}

function createStyleElement() {
	var styleElement = document.createElement("style");
	var head = getHeadElement();
	styleElement.type = "text/css";
	head.appendChild(styleElement);
	return styleElement;
}

function addStyle(obj, options) {
	var styleElement, update, remove;

	if (options.singleton) {
		var styleIndex = singletonCounter++;
		styleElement = singletonElement || (singletonElement = createStyleElement());
		update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
		remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
	} else {
		styleElement = createStyleElement();
		update = applyToTag.bind(null, styleElement);
		remove = function () {
			styleElement.parentNode.removeChild(styleElement);
		};
	}

	update(obj);

	return function updateStyle(newObj) {
		if(newObj) {
			if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
				return;
			update(obj = newObj);
		} else {
			remove();
		}
	};
}

function replaceText(source, id, replacement) {
	var boundaries = ["/** >>" + id + " **/", "/** " + id + "<< **/"];
	var start = source.lastIndexOf(boundaries[0]);
	var wrappedReplacement = replacement
		? (boundaries[0] + replacement + boundaries[1])
		: "";
	if (source.lastIndexOf(boundaries[0]) >= 0) {
		var end = source.lastIndexOf(boundaries[1]) + boundaries[1].length;
		return source.slice(0, start) + wrappedReplacement + source.slice(end);
	} else {
		return source + wrappedReplacement;
	}
}

function applyToSingletonTag(styleElement, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = replaceText(styleElement.styleSheet.cssText, index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = styleElement.childNodes;
		if (childNodes[index]) styleElement.removeChild(childNodes[index]);
		if (childNodes.length) {
			styleElement.insertBefore(cssNode, childNodes[index]);
		} else {
			styleElement.appendChild(cssNode);
		}
	}
}

function applyToTag(styleElement, obj) {
	var css = obj.css;
	var media = obj.media;
	var sourceMap = obj.sourceMap;

	if(sourceMap && typeof btoa === "function") {
		try {
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(JSON.stringify(sourceMap)) + " */";
			css = "@import url(\"data:stylesheet/css;base64," + btoa(css) + "\")";
		} catch(e) {}
	}

	if(media) {
		styleElement.setAttribute("media", media)
	}

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = css;
	} else {
		while(styleElement.firstChild) {
			styleElement.removeChild(styleElement.firstChild);
		}
		styleElement.appendChild(document.createTextNode(css));
	}
}
<commit_msg>Fix mime type<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var stylesInDom = {},
	memoize = function(fn) {
		var memo;
		return function () {
			if (typeof memo === "undefined") memo = fn.apply(this, arguments);
			return memo;
		};
	},
	isIE9 = memoize(function() {
		return /msie 9\b/.test(window.navigator.userAgent.toLowerCase());
	}),
	getHeadElement = memoize(function () {
		return document.head || document.getElementsByTagName("head")[0];
	}),
	singletonElement = null,
	singletonCounter = 0;

module.exports = function(list, options) {
	if(typeof DEBUG !== "undefined" && DEBUG) {
		if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};
	// Force single-tag solution on IE9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (typeof options.singleton === "undefined") options.singleton = isIE9();

	var styles = listToStyles(list);
	addStylesToDom(styles, options);

	return function update(newList) {
		var mayRemove = [];
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			domStyle.refs--;
			mayRemove.push(domStyle);
		}
		if(newList) {
			var newStyles = listToStyles(newList);
			addStylesToDom(newStyles, options);
		}
		for(var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];
			if(domStyle.refs === 0) {
				for(var j = 0; j < domStyle.parts.length; j++)
					domStyle.parts[j]();
				delete stylesInDom[domStyle.id];
			}
		}
	};
}

function addStylesToDom(styles, options) {
	for(var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];
		if(domStyle) {
			domStyle.refs++;
			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}
			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];
			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}
			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles(list) {
	var styles = [];
	var newStyles = {};
	for(var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};
		if(!newStyles[id])
			styles.push(newStyles[id] = {id: id, parts: [part]});
		else
			newStyles[id].parts.push(part);
	}
	return styles;
}

function createStyleElement() {
	var styleElement = document.createElement("style");
	var head = getHeadElement();
	styleElement.type = "text/css";
	head.appendChild(styleElement);
	return styleElement;
}

function addStyle(obj, options) {
	var styleElement, update, remove;

	if (options.singleton) {
		var styleIndex = singletonCounter++;
		styleElement = singletonElement || (singletonElement = createStyleElement());
		update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
		remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
	} else {
		styleElement = createStyleElement();
		update = applyToTag.bind(null, styleElement);
		remove = function () {
			styleElement.parentNode.removeChild(styleElement);
		};
	}

	update(obj);

	return function updateStyle(newObj) {
		if(newObj) {
			if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
				return;
			update(obj = newObj);
		} else {
			remove();
		}
	};
}

function replaceText(source, id, replacement) {
	var boundaries = ["/** >>" + id + " **/", "/** " + id + "<< **/"];
	var start = source.lastIndexOf(boundaries[0]);
	var wrappedReplacement = replacement
		? (boundaries[0] + replacement + boundaries[1])
		: "";
	if (source.lastIndexOf(boundaries[0]) >= 0) {
		var end = source.lastIndexOf(boundaries[1]) + boundaries[1].length;
		return source.slice(0, start) + wrappedReplacement + source.slice(end);
	} else {
		return source + wrappedReplacement;
	}
}

function applyToSingletonTag(styleElement, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = replaceText(styleElement.styleSheet.cssText, index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = styleElement.childNodes;
		if (childNodes[index]) styleElement.removeChild(childNodes[index]);
		if (childNodes.length) {
			styleElement.insertBefore(cssNode, childNodes[index]);
		} else {
			styleElement.appendChild(cssNode);
		}
	}
}

function applyToTag(styleElement, obj) {
	var css = obj.css;
	var media = obj.media;
	var sourceMap = obj.sourceMap;

	if(sourceMap && typeof btoa === "function") {
		try {
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(JSON.stringify(sourceMap)) + " */";
			css = "@import url(\"data:text/css;base64," + btoa(css) + "\")";
		} catch(e) {}
	}

	if(media) {
		styleElement.setAttribute("media", media)
	}

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = css;
	} else {
		while(styleElement.firstChild) {
			styleElement.removeChild(styleElement.firstChild);
		}
		styleElement.appendChild(document.createTextNode(css));
	}
}
<|endoftext|>


<commit_before>import React, { useState } from 'react';
import { c } from 'ttag';

import { resetVPNSettings } from 'proton-shared/lib/api/vpn';
import { Button, Alert, Row, Field, Label, Copy, PrimaryButton } from '../../../components';
import { useUserVPN, useApi, useNotifications, useLoading } from '../../../hooks';

const OpenVPNAccountSection = () => {
    const [updating, withUpdating] = useLoading();
    const { result = {}, fetch: fetchUserVPN } = useUserVPN();
    const { VPN = {} } = result;
    const { Name = '', Password = '' } = VPN;
    const [show, setShow] = useState(false);
    const api = useApi();
    const { createNotification } = useNotifications();

    const handleResetCredentials = async () => {
        await api(resetVPNSettings());
        await fetchUserVPN();

        createNotification({ text: c('Notification').t`OpenVPN / IKEv2 credentials regenerated` });
    };

    return (
        <>
            <Alert learnMore="https://protonvpn.com/support/vpn-login/">
                {c('Info')
                    .t`Use the following credentials when connecting to ProtonVPN servers without application. Examples use cases include: Tunnelblick on macOS, OpenVPN on GNU/Linux.
                    Do not use the OpenVPN / IKEv2 credentials in ProtonVPN applications or on the ProtonVPN dashboard.`}
            </Alert>
            <Row>
                {c('Label').t`OpenVPN / IKEv2 username`}
                <Field>

                        {Name}

                </Field>

                    <Copy value={Name} />

            </Row>
            <Row>
                {c('Label').t`OpenVPN / IKEv2 password`}
                <Field>

                        {show ? Password : '••••••••••••••••••••'}

                    <PrimaryButton
                        disabled={!Name || !Password}
                        loading={updating}
                        onClick={() => withUpdating(handleResetCredentials())}
                    >{c('Action').t`Reset credentials`}</PrimaryButton>
                </Field>

                    <Copy className="mr1" value={Password} />
                    <Button
                        icon={show ? 'unread' : 'read'}
                        onClick={() => setShow(!show)}
                        title={show ? c('Action').t`Hide` : c('Action').t`Show`}
                    />

            </Row>
        </>
    );
};

export default OpenVPNAccountSection;
<commit_msg>[VPNFE-141]Show full username and pass (OpenVPN / IKEv2 username )<commit_after>import React, { useState } from 'react';
import { c } from 'ttag';

import { resetVPNSettings } from 'proton-shared/lib/api/vpn';
import { Button, Alert, Copy, PrimaryButton } from '../../../components';
import { useUserVPN, useApi, useNotifications, useLoading } from '../../../hooks';

const OpenVPNAccountSection = () => {
    const [updating, withUpdating] = useLoading();
    const { result = {}, fetch: fetchUserVPN } = useUserVPN();
    const { VPN = {} } = result;
    const { Name = '', Password = '' } = VPN;
    const [show, setShow] = useState(false);
    const api = useApi();
    const { createNotification } = useNotifications();

    const handleResetCredentials = async () => {
        await api(resetVPNSettings());
        await fetchUserVPN();

        createNotification({ text: c('Notification').t`OpenVPN / IKEv2 credentials regenerated` });
    };

    return (
        <>
            <Alert learnMore="https://protonvpn.com/support/vpn-login/">
                {c('Info')
                    .t`Use the following credentials when connecting to ProtonVPN servers without application. Examples use cases include: Tunnelblick on macOS, OpenVPN on GNU/Linux.
                    Do not use the OpenVPN / IKEv2 credentials in ProtonVPN applications or on the ProtonVPN dashboard.`}
            </Alert>

                {c('Label').t`OpenVPN / IKEv2 username`}

                    {Name}

                    <Copy className="button--for-icon pt0-5 pb0-5" value={Name} />

                {c('Label').t`OpenVPN / IKEv2 password`}

                    {show ? Password : '••••••••••••••••'}

                    <Copy className="mr1 button--for-icon" value={Password} />
                    <Button
                        icon={show ? 'unread' : 'read'}
                        onClick={() => setShow(!show)}
                        title={show ? c('Action').t`Hide` : c('Action').t`Show`}
                    />

            <PrimaryButton
                disabled={!Name || !Password}
                loading={updating}
                onClick={() => withUpdating(handleResetCredentials())}
            >{c('Action').t`Reset credentials`}</PrimaryButton>
        </>
    );
};

export default OpenVPNAccountSection;
<|endoftext|>


<commit_before>/**
 * Copyright 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.blotter.contextmenu',
    dependencies: [],
    obj: function () {
        return function (cell, event) {
            var module = this;
            module.context_items = function (cell) {
                var items = [];
                // when aggregated the portfolio node structure is not shown so edit/add is not possible
                if (og.analytics.url && og.analytics.url.last.main.aggregators.length) {
                     items.push({name: 'Unable to add/edit trades whilst aggregated', handler: $.noop});
                     return items;
                }
                // positions with no trades first need a trade created based on the position
                var position_edit = function () {
                    var arr = cell.row_value.positionId.split('~'), id = arr[0] + '~' + arr[1];
                    og.api.rest.blotter.positions.get({id: id}).pipe(function (data) {
                        new og.blotter.Dialog({
                            details: data, portfolio:{name: id, id: id},
                            handler: function (data) {return og.api.rest.blotter.positions.put(data);}
                        });
                    });
                };
                // editing a trade just needs trade details
                var trade_edit = function () {
                    og.api.rest.blotter.trades.get({id: cell.row_value.tradeId}).pipe(function (data) {
                        new og.blotter.Dialog({
                            details: data, portfolio:{name: cell.row_value.nodeId, id: cell.row_value.nodeId},
                            handler: function (data) {return og.api.rest.blotter.trades.put(data);}
                        });
                    });
                };
                // addding a new trade needs a node id to append to
                var trade_insert_node = function () {
                    console.log(cell);
                    new og.blotter.Dialog({portfolio:{name: cell.row_value.nodeId, id: cell.row_value.nodeId},
                        handler: function (data) {return og.api.rest.blotter.trades.put(data);}
                    });
                };
                // addding a new trade to an exisiting position needs a position id to append to
                var trade_insert_position = function () {
                    console.log(cell);
                    new og.blotter.Dialog({portfolio:{name: cell.row_value.positionId, id: cell.row_value.positionId},
                        handler: function (data) {return og.api.rest.blotter.trades.put(data);}
                    });
                };
                var trade_delete = function () {
                    og.common.util.ui.dialog({
                        type: 'confirm',
                        title: 'Delete Trade / Position?',
                        width: 400, height: 190,
                        message: 'Are you sure you want to permanently delete this trade / position?',
                        buttons: {
                            'Delete': function () {/*do something*/},
                            'Cancel': function () {$(this).dialog('close');}
                        }
                    });
                };
                if (cell.type === "POSITION")
                    items.push({name: 'Add Trade', handler: position_edit});
                else
                    items.push({name: 'Add Trade', handler: trade_insert_node});
                // if a row is a node only the add new trade option is relevant
                if (cell.row in og.analytics.grid.state.nodes || cell.type === "NODE") {
                    return items;
                }
                // if a cell has a tradeId then edit the trade otherwise it is an empty position
                if (cell.row_value.tradeId) {
                    items.push({name: 'Edit Trade', handler: trade_edit});
                }
                else {
                    items.push({name: 'Edit Trade', handler: position_edit});
                }
                //items.push({name: 'Delete', handler: trade_delete});
                return items;
            };
            return og.common.util.ui.contextmenu({
                defaults: true, zindex: 4, items: module.context_items(cell)}, event, cell);
        };
    }
});<commit_msg>correct context menu options for varios trade/row types<commit_after>/**
 * Copyright 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.blotter.contextmenu',
    dependencies: [],
    obj: function () {
        return function (cell, event) {
            var module = this;
            module.context_items = function (cell) {
                var items = [];
                // when aggregated the portfolio node structure is not shown so edit/add is not possible
                if (og.analytics.url && og.analytics.url.last.main.aggregators.length) {
                     items.push({name: 'Unable to add/edit trades whilst aggregated', handler: $.noop});
                     return items;
                }
                // positions with no trades first need a trade created based on the position
                // trades added to positions need to be locked in to the same trade/security type
                var position_edit_insert = function () {
                    var arr = cell.row_value.positionId.split('~'), id = arr[0] + '~' + arr[1];
                    og.api.rest.blotter.positions.get({id: id}).pipe(function (data) {
                        new og.blotter.Dialog({
                            details: data, portfolio:{name: id, id: id},
                            handler: function (data) {return og.api.rest.blotter.positions.put(data);}
                        });
                    });
                };
                // editing a trade just needs trade details
                var trade_edit = function () {
                    og.api.rest.blotter.trades.get({id: cell.row_value.tradeId}).pipe(function (data) {
                        new og.blotter.Dialog({
                            details: data, portfolio:{name: cell.row_value.nodeId, id: cell.row_value.nodeId},
                            handler: function (data) {return og.api.rest.blotter.trades.put(data);}
                        });
                    });
                };
                // addding a new trade needs a node id to append to
                var trade_insert_node = function () {
                    new og.blotter.Dialog({portfolio:{name: cell.row_value.nodeId, id: cell.row_value.nodeId},
                        handler: function (data) {return og.api.rest.blotter.trades.put(data);}
                    });
                };
                var trade_delete = function () {
                    og.common.util.ui.dialog({
                        type: 'confirm',
                        title: 'Delete Trade / Position?',
                        width: 400, height: 190,
                        message: 'Are you sure you want to permanently delete this trade / position?',
                        buttons: {
                            'Delete': function () {/*do something*/},
                            'Cancel': function () {$(this).dialog('close');}
                        }
                    });
                };
                // if a row is a node AND the cell is a position only the position insert option is relevant
                // if a row is a node OR the cell is a node only the add new trade option is relevant
                if (cell.row in og.analytics.grid.state.nodes && cell.type === 'POSITION') {
                    items.push({name: 'Add Trade', handler: position_edit_insert});
                    return items;
                }
                else if (cell.row in og.analytics.grid.state.nodes || cell.type === 'NODE') {
                    items.push({name: 'Add Trade', handler: trade_insert_node});
                    return items;
                }
                // if a cell has a tradeId then edit the trade otherwise it is an empty position
                if (cell.row_value.tradeId) {
                    items.push({name: 'Edit Trade', handler: trade_edit});
                }
                else {
                    items.push({name: 'Edit Trade', handler: position_edit_insert});
                }
                //items.push({name: 'Delete', handler: trade_delete});
                return items;
            };
            return og.common.util.ui.contextmenu({
                defaults: true, zindex: 4, items: module.context_items(cell)}, event, cell);
        };
    }
});<|endoftext|>


<commit_before>// @ts-nocheck
import React from 'react'
import { Component } from 'react'
import * as PropTypes from 'prop-types'
import Radio from 'antd/lib/radio'
import 'antd/lib/radio/style/css'
import Card from 'antd/lib/card'
import 'antd/lib/card/style/css'
import Row from 'antd/lib/row'
import 'antd/lib/row/style/css'
import Col from 'antd/lib/col'
import 'antd/lib/col/style/css'
import Tooltip from 'antd/lib/tooltip'
import 'antd/lib/tooltip/style/css'
import Switch from 'antd/lib/switch'
import 'antd/lib/switch/style/css'
import Input from 'antd/lib/input'
import 'antd/lib/input/style/css'
import {
  Icon, LoaderText, DraggableVersionPanels
} from '../../components'
import ProjectVersionPanels from './ProjectVersionPanels'
import TMMergeProjectTMOptions from './TMMergeProjectTMOptions'

import {
  ProjectType, FromProjectVersionType
} from '../../utils/prop-types-util'

const DO_NOT_RENDER = undefined
const ALL = 'ALL'
const SAME = 'SAME'
const OTHER = 'OTHER'

const fromProjectSourceTooltip = (

    Exact text matches from projects are used before exact matches in imported
    TM. Fuzzy text matches from projects are used before fuzzy matches in
    imported TM.

)

const Search = Input.Search

/*
 * Component to display TM merge from project sources
 */
class TMMergeProjectSources extends Component {
  static propTypes = {
    projectVersions: PropTypes.arrayOf(ProjectType).isRequired,
    fetchingProject: PropTypes.bool.isRequired,
    mergeOptions: PropTypes.shape({
      selectedVersions: PropTypes.arrayOf(FromProjectVersionType),
      projectSearchTerm: PropTypes.string
    }).isRequired,
    onFromAllProjectsChange: PropTypes.func.isRequired,
    onProjectSearchChange: PropTypes.func.isRequired,
    flushProjectSearch: PropTypes.func.isRequired,
    onVersionCheckboxChange: PropTypes.func.isRequired,
    onAllVersionCheckboxChange: PropTypes.func.isRequired,
    onDragMoveEnd: PropTypes.func.isRequired,
    removeProjectVersion: PropTypes.func.isRequired,
    thisProjectSlug: PropTypes.string.isRequired
  }
  defaultState = {
    fromProjectSelection: SAME,
    enabled: true
  }
  constructor (props) {
    super(props)
    this.state = this.defaultState
  }
  onFromProjectSelectionChange = (value) => () => {
    this.setState((prevState, props) => ({
      fromProjectSelection: value
    }))
    if (value === ALL) {
      this.props.onFromAllProjectsChange()
    }
    if (value === SAME) {
      // if user select this project, we should search for current project
      this.props.onProjectSearchChange(this.props.thisProjectSlug)
    }
  }
  projectSearchTermChanged = e => {
    const text = e.target.value
    this.props.onProjectSearchChange(text)
  }
  toggleChange = (e) => {
    const checked = e.target.checked
    this.setState((prevState) => ({
      enabled: checked
    }))
  }
  render () {
    const {
      projectVersions,
      fetchingProject,
      mergeOptions,
      flushProjectSearch,
      onVersionCheckboxChange,
      onAllVersionCheckboxChange,
      onDragMoveEnd,
      removeProjectVersion
    } = this.props
    const disabled = !this.state.enabled
    const noResults = (projectVersions.length === 0) ? 'No results' : ''
    const fromVersionsPanel = this.state.fromProjectSelection === ALL ||
    disabled
      ? DO_NOT_RENDER
      : (

        <Search
          placeholder='input search text'
          onPressEnter={flushProjectSearch}
          onSearch={this.projectSearchTermChange}
          enterButton />
        <Row>
          <Col span={11} className='mr2'>

              Select source project versions to merge

              <LoaderText loading={fetchingProject}
                loadingText={'Fetching Projects'} />
              {noResults}

            <ProjectVersionPanels projectVersions={projectVersions}
              selectedVersions={mergeOptions.selectedVersions}
              onVersionCheckboxChange={onVersionCheckboxChange}
              onAllVersionCheckboxChange={onAllVersionCheckboxChange} />
          </Col>
          <Col span={11}>
            <DraggableVersionPanels
              selectedVersions={mergeOptions.selectedVersions}
              onDraggableMoveEnd={onDragMoveEnd}
              removeVersion={removeProjectVersion} />
          </Col>
        </Row>

      )
    const disableDiffProjectOption = this.state.fromProjectSelection === SAME
    return (

        <Row>
          <Col span={24} className='v-mid'>
            <Switch defaultChecked
              onChange={this.toggleChange} />
            From
            Project Source
            <Tooltip placement='right'
              title={fromProjectSourceTooltip}>

                <Icon name='info' className='s0' />

            </Tooltip>
          </Col>
        </Row>
        <Row className='mt2 mb2'>
          <Col span={6}>
            Search TM from
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === SAME}
              onChange={this.onFromProjectSelectionChange(SAME)}> this project
            </Radio>
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === ALL}
              onChange={this.onFromProjectSelectionChange(ALL)}> all projects
            </Radio>
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === OTHER}
              onChange={this.onFromProjectSelectionChange(OTHER)}>
              some projects
            </Radio>
          </Col>
          {fromVersionsPanel}
          <TMMergeProjectTMOptions {...this.props} disabled={disabled}
            disableDifferentProjectOption={disableDiffProjectOption} />
        </Row>
        <Row className='mt4 mb4'>
          <Col span={24}>
            <Card>

Translations which satisfy all conditions will copy as
                 translated.

            </Card>
          </Col>
        </Row>

    )
  }
}

export default TMMergeProjectSources
<commit_msg>fix: projectSearchTermChanged function<commit_after>// @ts-nocheck
import React from 'react'
import { Component } from 'react'
import * as PropTypes from 'prop-types'
import Radio from 'antd/lib/radio'
import 'antd/lib/radio/style/css'
import Card from 'antd/lib/card'
import 'antd/lib/card/style/css'
import Row from 'antd/lib/row'
import 'antd/lib/row/style/css'
import Col from 'antd/lib/col'
import 'antd/lib/col/style/css'
import Tooltip from 'antd/lib/tooltip'
import 'antd/lib/tooltip/style/css'
import Switch from 'antd/lib/switch'
import 'antd/lib/switch/style/css'
import Input from 'antd/lib/input'
import 'antd/lib/input/style/css'
import {
  Icon, LoaderText, DraggableVersionPanels
} from '../../components'
import ProjectVersionPanels from './ProjectVersionPanels'
import TMMergeProjectTMOptions from './TMMergeProjectTMOptions'

import {
  ProjectType, FromProjectVersionType
} from '../../utils/prop-types-util'

const DO_NOT_RENDER = undefined
const ALL = 'ALL'
const SAME = 'SAME'
const OTHER = 'OTHER'

const fromProjectSourceTooltip = (

    Exact text matches from projects are used before exact matches in imported
    TM. Fuzzy text matches from projects are used before fuzzy matches in
    imported TM.

)

const Search = Input.Search

/*
 * Component to display TM merge from project sources
 */
class TMMergeProjectSources extends Component {
  static propTypes = {
    projectVersions: PropTypes.arrayOf(ProjectType).isRequired,
    fetchingProject: PropTypes.bool.isRequired,
    mergeOptions: PropTypes.shape({
      selectedVersions: PropTypes.arrayOf(FromProjectVersionType),
      projectSearchTerm: PropTypes.string
    }).isRequired,
    onFromAllProjectsChange: PropTypes.func.isRequired,
    onProjectSearchChange: PropTypes.func.isRequired,
    flushProjectSearch: PropTypes.func.isRequired,
    onVersionCheckboxChange: PropTypes.func.isRequired,
    onAllVersionCheckboxChange: PropTypes.func.isRequired,
    onDragMoveEnd: PropTypes.func.isRequired,
    removeProjectVersion: PropTypes.func.isRequired,
    thisProjectSlug: PropTypes.string.isRequired
  }
  defaultState = {
    fromProjectSelection: SAME,
    enabled: true
  }
  constructor (props) {
    super(props)
    this.state = this.defaultState
  }
  onFromProjectSelectionChange = (value) => () => {
    this.setState((prevState, props) => ({
      fromProjectSelection: value
    }))
    if (value === ALL) {
      this.props.onFromAllProjectsChange()
    }
    if (value === SAME) {
      // if user select this project, we should search for current project
      this.props.onProjectSearchChange(this.props.thisProjectSlug)
    }
  }
  projectSearchTermChanged = e => {
    const text = e.target.value
    this.props.onProjectSearchChange(text)
  }
  toggleChange = (e) => {
    const checked = e.target.checked
    this.setState((prevState) => ({
      enabled: checked
    }))
  }
  render () {
    const {
      projectVersions,
      fetchingProject,
      mergeOptions,
      flushProjectSearch,
      onVersionCheckboxChange,
      onAllVersionCheckboxChange,
      onDragMoveEnd,
      removeProjectVersion
    } = this.props
    const disabled = !this.state.enabled
    const noResults = (projectVersions.length === 0) ? 'No results' : ''
    const fromVersionsPanel = this.state.fromProjectSelection === ALL ||
    disabled
      ? DO_NOT_RENDER
      : (

        <Search
          placeholder='input search text'
          onPressEnter={flushProjectSearch}
          onSearch={this.projectSearchTermChanged}
          enterButton />
        <Row>
          <Col span={11} className='mr2'>

              Select source project versions to merge

              <LoaderText loading={fetchingProject}
                loadingText={'Fetching Projects'} />
              {noResults}

            <ProjectVersionPanels projectVersions={projectVersions}
              selectedVersions={mergeOptions.selectedVersions}
              onVersionCheckboxChange={onVersionCheckboxChange}
              onAllVersionCheckboxChange={onAllVersionCheckboxChange} />
          </Col>
          <Col span={11}>
            <DraggableVersionPanels
              selectedVersions={mergeOptions.selectedVersions}
              onDraggableMoveEnd={onDragMoveEnd}
              removeVersion={removeProjectVersion} />
          </Col>
        </Row>

      )
    const disableDiffProjectOption = this.state.fromProjectSelection === SAME
    return (

        <Row>
          <Col span={24} className='v-mid'>
            <Switch defaultChecked
              onChange={this.toggleChange} />
            From
            Project Source
            <Tooltip placement='right'
              title={fromProjectSourceTooltip}>

                <Icon name='info' className='s0' />

            </Tooltip>
          </Col>
        </Row>
        <Row className='mt2 mb2'>
          <Col span={6}>
            Search TM from
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === SAME}
              onChange={this.onFromProjectSelectionChange(SAME)}> this project
            </Radio>
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === ALL}
              onChange={this.onFromProjectSelectionChange(ALL)}> all projects
            </Radio>
          </Col>
          <Col span={6}>
            <Radio name='fromProjectSelection' inline disabled={disabled}
              checked={this.state.fromProjectSelection === OTHER}
              onChange={this.onFromProjectSelectionChange(OTHER)}>
              some projects
            </Radio>
          </Col>
          {fromVersionsPanel}
          <TMMergeProjectTMOptions {...this.props} disabled={disabled}
            disableDifferentProjectOption={disableDiffProjectOption} />
        </Row>
        <Row className='mt4 mb4'>
          <Col span={24}>
            <Card>

Translations which satisfy all conditions will copy as
                 translated.

            </Card>
          </Col>
        </Row>

    )
  }
}

export default TMMergeProjectSources
<|endoftext|>


<commit_before>var TextBooks = {
    term: undefined,

    show_books: function(term, textbook) {
        //Navbar.render_navbar("nav-sub");
        TextBooks.term = term;
        showLoading();
        CommonLoading.render_init();
        WSData.fetch_book_data(term, TextBooks.render_books, TextBooks.render_error);
        WSData.fetch_course_data_for_term(TextBooks.term, TextBooks.render_books, TextBooks.render_error);
        WSData.fetch_instructed_course_data_for_term(TextBooks.term, TextBooks.render_books, TextBooks.render_error);
    },

    render_error: function() {
        var book_err_status = WSData.book_data_error_code(TextBooks.term);
        var course_err_status = WSData.course_data_error_code(TextBooks.term);
        var instructed_course_err_status = WSData.instructed_course_data_error_code(TextBooks.term);

        if (book_err_status === 543 || course_err_status === 543 || instructed_course_err_status === 543) {
            var raw = CardWithError.render("Textbooks");
            $("#main-content").html(raw);
        }
    },

    process_book_data: function(book_data, course_data, instructed_course_data) {
        var template_data = {
            "sections": [],
            "quarter": course_data ? course_data.quarter : instructed_course_data.quarter,
            "year": course_data ? course_data.year: instructed_course_data.year,
            "summer_term": course_data ? course_data.summer_term : instructed_course_data.summer_term
        };

        var section_data = function (i, section, instructor) {
            return {
                index: i,
                section_title: section.course_title,
                curriculum: section.curriculum_abbr,
                course_number: section.course_number,
                section_id: section.section_id,
                color_id: section.color_id,
                sln: section.sln,
                books: book_data ? book_data[section.sln] : [],
                is_instructor: instructor,
                bothell_campus: section.course_campus.toLowerCase() === 'bothell',
                tacoma_campus: section.course_campus.toLowerCase() === 'tacoma'
            };
        };

        if (course_data) {
            $.each(course_data.sections, function (index) {
                template_data.sections.push(section_data(index, this, false));
            });
        }

        if (myuwFeatureEnabled('instructor_textbooks') && instructed_course_data) {
            $.each(instructed_course_data.sections, function (index) {
                template_data.sections.push(section_data(index, this, true));
            });
        }

        template_data.verba_link = book_data ? book_data.verba_link : null;
        return template_data;
    },

    _has_all_data: function () {
        var book_data = WSData.book_data(TextBooks.term);
        var course_data = WSData.course_data_for_term(TextBooks.term);
        var instructed_course_data = WSData.instructed_course_data_for_term(TextBooks.term);
        var book_data_err_status = WSData.course_data_error_code(TextBooks.term);
        var course_err_status = WSData.course_data_error_code(TextBooks.term);
        var instructed_course_err_status = WSData.instructed_course_data_error_code(TextBooks.term);

        return ((book_data ||
                 (book_data === undefined && book_data_err_status === 404)) &&
                (course_data ||
                 (course_data === undefined && course_err_status === 404)) &&
                (instructed_course_data ||
                 (instructed_course_data === undefined && instructed_course_err_status === 404)));
    },

    render_books: function() {
        if(!TextBooks._has_all_data()){
            return;
        }
        var term = TextBooks.term;
        $('html,body').animate({scrollTop: 0}, 'fast');
        var source   = $("#textbooks").html();
        var template = Handlebars.compile(source);
        var template_data = TextBooks.process_book_data(WSData.book_data(term),
                                                        WSData.course_data_for_term(term),
                                                        WSData.instructed_course_data_for_term(term));
        if (template_data !== undefined){
            $("#main-content").html(template(template_data));
        }

        // Scroll to correct section
        element = $("a[name='" + location.hash.substring(1) + "']");
        if (element.length > 0) {
                $('html, body').animate({
                scrollTop: element.offset().top
            });
        }
    }
};

/* node.js exports */
if (typeof exports == "undefined") {
    var exports = {};
}
exports.TextBooks = TextBooks;
<commit_msg>textbooks render on allowable errors<commit_after>var TextBooks = {
    term: undefined,

    show_books: function(term, textbook) {
        //Navbar.render_navbar("nav-sub");
        TextBooks.term = term;
        showLoading();
        CommonLoading.render_init();
        WSData.fetch_book_data(term, TextBooks.render_books, TextBooks.render_error);
        WSData.fetch_course_data_for_term(TextBooks.term, TextBooks.render_books, TextBooks.render_error);
        WSData.fetch_instructed_course_data_for_term(TextBooks.term, TextBooks.render_books, TextBooks.render_error);
    },

    render_error: function() {
        var book_err_status = WSData.book_data_error_code(TextBooks.term);
        var course_err_status = WSData.course_data_error_code(TextBooks.term);
        var instructed_course_err_status = WSData.instructed_course_data_error_code(TextBooks.term);

        if (book_err_status === 543 || course_err_status === 543 || instructed_course_err_status === 543) {
            var raw = CardWithError.render("Textbooks");
            $("#main-content").html(raw);
        } else {
            TextBooks.render_books();
        }
    },

    process_book_data: function(book_data, course_data, instructed_course_data) {
        var template_data = {
            "sections": [],
            "quarter": course_data ? course_data.quarter : instructed_course_data.quarter,
            "year": course_data ? course_data.year: instructed_course_data.year,
            "summer_term": course_data ? course_data.summer_term : instructed_course_data.summer_term
        };

        var section_data = function (i, section, instructor) {
            return {
                index: i,
                section_title: section.course_title,
                curriculum: section.curriculum_abbr,
                course_number: section.course_number,
                section_id: section.section_id,
                color_id: section.color_id,
                sln: section.sln,
                books: book_data ? book_data[section.sln] : [],
                is_instructor: instructor,
                bothell_campus: section.course_campus.toLowerCase() === 'bothell',
                tacoma_campus: section.course_campus.toLowerCase() === 'tacoma'
            };
        };

        if (course_data) {
            $.each(course_data.sections, function (index) {
                template_data.sections.push(section_data(index, this, false));
            });
        }

        if (myuwFeatureEnabled('instructor_textbooks') && instructed_course_data) {
            $.each(instructed_course_data.sections, function (index) {
                template_data.sections.push(section_data(index, this, true));
            });
        }

        template_data.verba_link = book_data ? book_data.verba_link : null;
        return template_data;
    },

    _has_all_data: function () {
        var book_data = WSData.book_data(TextBooks.term);
        var course_data = WSData.course_data_for_term(TextBooks.term);
        var instructed_course_data = WSData.instructed_course_data_for_term(TextBooks.term);
        var book_data_err_status = WSData.course_data_error_code(TextBooks.term);
        var course_err_status = WSData.course_data_error_code(TextBooks.term);
        var instructed_course_err_status = WSData.instructed_course_data_error_code(TextBooks.term);

        return ((book_data ||
                 (book_data === undefined && book_data_err_status === 404)) &&
                (course_data ||
                 (course_data === undefined && course_err_status === 404)) &&
                (instructed_course_data ||
                 (instructed_course_data === undefined && instructed_course_err_status === 404)));
    },

    render_books: function() {
        if(!TextBooks._has_all_data()){
            return;
        }
        var term = TextBooks.term;
        $('html,body').animate({scrollTop: 0}, 'fast');
        var source   = $("#textbooks").html();
        var template = Handlebars.compile(source);
        var template_data = TextBooks.process_book_data(WSData.book_data(term),
                                                        WSData.course_data_for_term(term),
                                                        WSData.instructed_course_data_for_term(term));
        if (template_data !== undefined){
            $("#main-content").html(template(template_data));
        }

        // Scroll to correct section
        element = $("a[name='" + location.hash.substring(1) + "']");
        if (element.length > 0) {
                $('html, body').animate({
                scrollTop: element.offset().top
            });
        }
    }
};

/* node.js exports */
if (typeof exports == "undefined") {
    var exports = {};
}
exports.TextBooks = TextBooks;
<|endoftext|>