<commit_before>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
define([
    'jquery',
    'sprintf',
    'datatables.net',
    'datatables.bootstrap'
], function($) {
    'use strict';
    var gMenuFmt,
        gSearchLanguage,
        gTable,
        gTableDom;

    gTableDom = '<"row"<"col-xs-12 col-sm-12 col-md-4 col-lg-4"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4"<"table-process">>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4"f>r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row paging"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>';

    gSearchLanguage = '
' +
        '' +
        '_INPUT_
';

    gMenuFmt = '_MENU_ %s';

    /**
     * Remove the focus from the element that triggers the event.
     * Apply a blur() to the triggering element.
     *
     * @private
     * @param {Event} event: The event triggering this function.
    **/
    function removeFocus(event) {
        var target;

        target = event.target || event.srcElement;
        if (event.keyCode === 27) {
            target.blur();
        }
    }

    var kciTable = {
        tableId: null,
        tableLoadingDivId: null,
        tableDivId: null,
        tableNode: null,
        tableLoadingNode: null,
        tableDivNode: null,
        table: null,
        oldSearch: null,
        inputNode: null,
        selectNode: null,
        _noIdURL: false,
        _rowURL: '/build/%(job)s/kernel/%(kernel)s/',
        _rowURLElements: ['job', 'kernel'],
        _clickFunction: null,
        _drawFunction: null,
        _lengthMenu: [25, 50, 75, 100],
        _order: [1, 'desc'],
        _dom: gTableDom,
        _data: null,
        _columns: null,
        _paging: true,
        _info: true,
        _languageLengthMenu:
            '_MENU_ reports per page',
        _languageZeroRecords: 'No data found.'
    };

    kciTable.settings = function() {
        return {
            language: {
                lengthMenu: this._languageLengthMenu,
                zeroRecords: this._languageZeroRecords,
                search: gSearchLanguage,
                searchPlaceholder: 'Filter the results'
            },
            search: {
                regex: true,
                smart: true
            },
            data: this._data,
            columns: this._columns,
            paging: this._paging,
            info: this._info,
            order: this._order,
            dom: this._dom,
            lengthMenu: this._lengthMenu,
            deferRender: true,
            ordering: true,
            stateSave: true,
            stateDuration: -1,
            processing: false
        };
    };

    kciTable.paging = function(value) {
        if (value !== undefined) {
            this._paging = Boolean(value);
            return this;
        }
        return this._paging;
    };

    kciTable.info = function(value) {
        if (value !== undefined) {
            this._info = Boolean(value);
            return this;
        }
        return this._info;
    };

    kciTable.setup = function() {
        if (this.tableId) {
            this.tableNode = document.getElementById(this.tableId);

            if (!this.tableNode) {
                throw 'No table ID DOM element found';
            }
        } else {
            throw 'No table ID defined';
        }

        if (this.tableLoadingDivId) {
            this.tableLoadingNode =
                document.getElementById(this.tableLoadingDivId);
        }

        if (this.tableDivId) {
            this.tableDivNode = document.getElementById(this.tableDivId);
        }

        return this;
    };

    kciTable.languageZeroRecords = function(value) {
        if (value !== null && value !== undefined) {
            this._languageZeroRecords = value;
            return this;
        }
        return this._languageZeroRecords;
    };

    kciTable.languageLengthMenu = function(value) {
        if (value !== null && value !== undefined) {
            this._languageLengthMenu = sprintf(gMenuFmt, value);
            return this;
        }
        return this._languageLengthMenu;
    };

    kciTable.rowURL = function(value) {
        if (value !== null && value !== undefined) {
            this._rowURL = value;
            return this;
        }
        return this._rowURL;
    };

    kciTable.rowURLElements = function(value) {
        if (value !== null && value !== undefined) {
            this._rowURLElements = value;
            return this;
        }
        return this._rowURLElements;
    };

    kciTable.order = function(value) {
        if (value !== null && value !== undefined) {
            this._order = value;
            return this;
        }
        return this._order;
    };

    kciTable.data = function(value) {
        if (value !== null && value !== undefined) {
            this._data = value;
            return this;
        }
        return this._data;
    };

    kciTable.columns = function(value) {
        if (value !== null && value !== undefined) {
            this._columns = value;
            return this;
        }
        return this._columns;
    };

    /**
     * Control whetever the link for the row click event should have an
     * '_id=' value appended.
     *
     * @param {Boolean} value: If the row link should have an ID or not.
    **/
    kciTable.noIdURL = function(value) {
        if (value !== undefined) {
            this._noIdURL = Boolean(value);
            return this;
        }
        return this._noIdURL;
    };

    kciTable.dom = function(value) {
        if (value !== null && value !== undefined) {
            this._dom = value;
            return this;
        }
        return this._dom;
    };

    /**
     * Get or set the length menu.
     * This is the menu with how many rows to show in the table.
     *
     * @param {Array} value: The array with the number of rows to show.
    **/
    kciTable.lengthMenu = function(value) {
        if (value !== null && value !== undefined) {
            this._lengthMenu = value;
            return this;
        }
        return this._lengthMenu;
    };

    /**
     * Get or set the row click function.
     * This is the function to be called when a row gets clicked.
     *
     * @param {Function} value: The function to associate with the click event.
    **/
    kciTable.clickFunction = function(value) {
        if (value !== null && value !== undefined) {
            this._clickFunction = value;
            return this;
        }
        return this._clickFunction;
    };

    /**
     * Perform a search on the table.
     * A draw() event will be fired.
     *
     * @param {String} value: The search string to perform.
    **/
    kciTable.search = function(value) {
        if (this.inputNode && this.inputNode.disabled) {
            this.inputNode.removeAttribute('disabled');
        }

        if (value && value.length > 0) {
            this.oldSearch = null;
            this.table.search(value, true, true).draw();
        }

        return this;
    };

    /**
     * Change the length of the tables, showing or hiding rows.
     * A draw() event will be fired.
     *
     * @param {String} value: The number of rows to show.
    **/
    kciTable.pageLen = function(value) {
        var len;

        if (value && value.length > 0) {
            len = Number(value);
            if (isNaN(len)) {
                len = this._lengthMenu[0];
            }
            this.table.page.len(len).draw();
        }

        return this;
    };

    /**
     * Associate a new function on the 'draw' event.
     * This is fired whenevr the table draw() event has been completed.
     *
     * @param {Function} func: The function to associate.
    **/
    kciTable.addDrawEvent = function(func) {
        if (func) {
            this.table.on('draw.dt', func);
        }
        return this;
    };

    /**
     * Add new rows to the table, updating and refreshing it.
     *
     * @param {object} value: The data that the rows will be built on.
     * It must be of the same type and with the same structure of the initial
     * data with which the table was populated.
    **/
    kciTable.addRows = function(value) {
        this.table.rows.add(value).draw();
    };

    /**
     * Draw the actual table and bind functions/events.
    **/
    kciTable.draw = function() {
        var settings,
            that;

        that = this;
        settings = that.settings();

        function _initComplete() {
            if (that.tableLoadingNode) {
                $(that.tableLoadingNode).remove();
            }

            if (that.tableDivNode) {
                that.inputNode =
                    that.tableDivNode.querySelector('input.input-sm');
                that.selectNode =
                    that.tableDivNode.querySelector('select.input-sm');
            } else {
                that.inputNode = document.querySelector('input.input-sm');
                that.selectNode = document.querySelector('select.input-sm');
            }

            if (that.inputNode) {
                // Remove focus from input when Esc is pressed.
                that.inputNode.addEventListener('keyup', removeFocus);
            }

            if (that.selectNode) {
                // Remove focus from the table length selection on Esc.
                that.selectNode.addEventListener('keyup', removeFocus);
            }
        }

        settings.initComplete = _initComplete;

        that.table = $(that.tableNode).DataTable(settings);

        if (that._drawFunction) {
            that.table.on('draw.dt', that._drawFunction);
        }

        if (that._clickFunction) {
            that.table.on('click', 'tbody tr', that._clickFunction);
        } else {
            that.table.on('click', 'tbody tr', function() {
                var location,
                    rowData,
                    substitutions;

                rowData = that.table.row(this).data();
                location = '#';
                substitutions = {};

                if (rowData) {
                    that._rowURLElements.forEach(function(value) {
                        substitutions[value] = rowData[value] || null;
                    });

                    location = sprintf(that._rowURL, substitutions);
                    if (!that._noIdURL && rowData._id) {
                        location += '?_id=' + rowData._id.$oid;
                    }
                }
                window.location = location;
            });
        }

        return this;
    };

    /**
     * Factory to create new table elements.
     *
     * @param {object} settings: The settings associated with the table.
    **/
    gTable = function(settings) {
        var key,
            newTable;

        newTable = Object.create(kciTable);

        if (settings) {
            for (key in settings) {
                if (settings.hasOwnProperty(key)) {
                    newTable[key] = settings[key];
                }
            }
        } else {
            throw 'No settings found';
        }

        return newTable.setup();
    };

    return gTable;
});
<commit_msg>Add invalidate function, remove variables<commit_after>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
define([
    'jquery',
    'sprintf',
    'datatables.net',
    'datatables.bootstrap'
], function($) {
    'use strict';
    var gMenuFmt,
        gSearchLanguage,
        gTable,
        gTableDom;

    gTableDom = '<"row"<"col-xs-12 col-sm-12 col-md-4 col-lg-4"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4"<"table-process">>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4"f>r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row paging"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>';

    gSearchLanguage = '
' +
        '' +
        '_INPUT_
';

    gMenuFmt = '_MENU_ %s';

    /**
     * Remove the focus from the element that triggers the event.
     * Apply a blur() to the triggering element.
     *
     * @private
     * @param {Event} event: The event triggering this function.
    **/
    function removeFocus(event) {
        var target;

        target = event.target || event.srcElement;
        if (event.keyCode === 27) {
            target.blur();
        }
    }

    var kciTable = {
        tableId: null,
        tableLoadingDivId: null,
        tableDivId: null,
        tableNode: null,
        tableLoadingNode: null,
        tableDivNode: null,
        table: null,
        inputNode: null,
        selectNode: null,
        _noIdURL: false,
        _rowURL: '/build/%(job)s/kernel/%(kernel)s/',
        _rowURLElements: ['job', 'kernel'],
        _clickFunction: null,
        _drawFunction: null,
        _lengthMenu: [25, 50, 75, 100],
        _order: [1, 'desc'],
        _dom: gTableDom,
        _data: null,
        _columns: null,
        _paging: true,
        _info: true,
        _languageLengthMenu:
            '_MENU_ reports per page',
        _languageZeroRecords: 'No data found.'
    };

    kciTable.settings = function() {
        return {
            language: {
                lengthMenu: this._languageLengthMenu,
                zeroRecords: this._languageZeroRecords,
                search: gSearchLanguage,
                searchPlaceholder: 'Filter the results'
            },
            search: {
                regex: true,
                smart: true
            },
            data: this._data,
            columns: this._columns,
            paging: this._paging,
            info: this._info,
            order: this._order,
            dom: this._dom,
            lengthMenu: this._lengthMenu,
            deferRender: true,
            ordering: true,
            stateSave: true,
            stateDuration: -1,
            processing: false
        };
    };

    kciTable.paging = function(value) {
        if (value !== undefined) {
            this._paging = Boolean(value);
            return this;
        }
        return this._paging;
    };

    kciTable.info = function(value) {
        if (value !== undefined) {
            this._info = Boolean(value);
            return this;
        }
        return this._info;
    };

    kciTable.setup = function() {
        if (this.tableId) {
            this.tableNode = document.getElementById(this.tableId);

            if (!this.tableNode) {
                throw 'No table ID DOM element found';
            }
        } else {
            throw 'No table ID defined';
        }

        if (this.tableLoadingDivId) {
            this.tableLoadingNode =
                document.getElementById(this.tableLoadingDivId);
        }

        if (this.tableDivId) {
            this.tableDivNode = document.getElementById(this.tableDivId);
        }

        return this;
    };

    kciTable.languageZeroRecords = function(value) {
        if (value !== null && value !== undefined) {
            this._languageZeroRecords = value;
            return this;
        }
        return this._languageZeroRecords;
    };

    kciTable.languageLengthMenu = function(value) {
        if (value !== null && value !== undefined) {
            this._languageLengthMenu = sprintf(gMenuFmt, value);
            return this;
        }
        return this._languageLengthMenu;
    };

    kciTable.rowURL = function(value) {
        if (value !== null && value !== undefined) {
            this._rowURL = value;
            return this;
        }
        return this._rowURL;
    };

    kciTable.rowURLElements = function(value) {
        if (value !== null && value !== undefined) {
            this._rowURLElements = value;
            return this;
        }
        return this._rowURLElements;
    };

    kciTable.order = function(value) {
        if (value !== null && value !== undefined) {
            this._order = value;
            return this;
        }
        return this._order;
    };

    kciTable.data = function(value) {
        if (value !== null && value !== undefined) {
            this._data = value;
            return this;
        }
        return this._data;
    };

    kciTable.columns = function(value) {
        if (value !== null && value !== undefined) {
            this._columns = value;
            return this;
        }
        return this._columns;
    };

    /**
     * Control whetever the link for the row click event should have an
     * '_id=' value appended.
     *
     * @param {Boolean} value: If the row link should have an ID or not.
    **/
    kciTable.noIdURL = function(value) {
        if (value !== undefined) {
            this._noIdURL = Boolean(value);
            return this;
        }
        return this._noIdURL;
    };

    kciTable.dom = function(value) {
        if (value !== null && value !== undefined) {
            this._dom = value;
            return this;
        }
        return this._dom;
    };

    /**
     * Get or set the length menu.
     * This is the menu with how many rows to show in the table.
     *
     * @param {Array} value: The array with the number of rows to show.
    **/
    kciTable.lengthMenu = function(value) {
        if (value !== null && value !== undefined) {
            this._lengthMenu = value;
            return this;
        }
        return this._lengthMenu;
    };

    /**
     * Get or set the row click function.
     * This is the function to be called when a row gets clicked.
     *
     * @param {Function} value: The function to associate with the click event.
    **/
    kciTable.clickFunction = function(value) {
        if (value !== null && value !== undefined) {
            this._clickFunction = value;
            return this;
        }
        return this._clickFunction;
    };

    /**
     * Perform a search on the table.
     * A draw() event will be fired.
     *
     * @param {String} value: The search string to perform.
    **/
    kciTable.search = function(value) {
        if (this.inputNode && this.inputNode.disabled) {
            this.inputNode.removeAttribute('disabled');
        }

        if (value && value.length > 0) {
            this.table.search(value, true).draw();
        }

        return this;
    };

    /**
     * Change the length of the tables, showing or hiding rows.
     * A draw() event will be fired.
     *
     * @param {String} value: The number of rows to show.
    **/
    kciTable.pageLen = function(value) {
        var len;

        if (value && value.length > 0) {
            len = Number(value);
            if (isNaN(len)) {
                len = this._lengthMenu[0];
            }
            this.table.page.len(len).draw();
        }

        return this;
    };

    /**
     * Invalidate the cache/data of a single column in the table.
     * It will invalidate all the cells of a column.
     *
     * @param {Number} index: The column index number.
    **/
    kciTable.invalidateColumn = function(index) {
        // Get all the cells for a single column.
        this.table.cells(undefined, index).invalidate();
        return this;
    };

    /**
     * Associate a new function on the 'draw' event.
     * This is fired whenevr the table draw() event has been completed.
     *
     * @param {Function} func: The function to associate.
    **/
    kciTable.addDrawEvent = function(func) {
        if (func) {
            this.table.on('draw.dt', func);
        }
        return this;
    };

    /**
     * Add new rows to the table, updating and refreshing it.
     *
     * @param {object} value: The data that the rows will be built on.
     * It must be of the same type and with the same structure of the initial
     * data with which the table was populated.
    **/
    kciTable.addRows = function(value) {
        this.table.rows.add(value).draw();
    };

    /**
     * Draw the actual table and bind functions/events.
    **/
    kciTable.draw = function() {
        var settings,
            that;

        that = this;
        settings = that.settings();

        function _initComplete() {
            if (that.tableLoadingNode) {
                $(that.tableLoadingNode).remove();
            }

            if (that.tableDivNode) {
                that.inputNode =
                    that.tableDivNode.querySelector('input.input-sm');
                that.selectNode =
                    that.tableDivNode.querySelector('select.input-sm');
            } else {
                that.inputNode = document.querySelector('input.input-sm');
                that.selectNode = document.querySelector('select.input-sm');
            }

            if (that.inputNode) {
                // Remove focus from input when Esc is pressed.
                that.inputNode.addEventListener('keyup', removeFocus);
            }

            if (that.selectNode) {
                // Remove focus from the table length selection on Esc.
                that.selectNode.addEventListener('keyup', removeFocus);
            }
        }

        settings.initComplete = _initComplete;

        that.table = $(that.tableNode).DataTable(settings);

        if (that._drawFunction) {
            that.table.on('draw.dt', that._drawFunction);
        }

        if (that._clickFunction) {
            that.table.on('click', 'tbody tr', that._clickFunction);
        } else {
            that.table.on('click', 'tbody tr', function() {
                var location,
                    rowData,
                    substitutions;

                rowData = that.table.row(this).data();
                location = '#';
                substitutions = {};

                if (rowData) {
                    that._rowURLElements.forEach(function(value) {
                        substitutions[value] = rowData[value] || null;
                    });

                    location = sprintf(that._rowURL, substitutions);
                    if (!that._noIdURL && rowData._id) {
                        location += '?_id=' + rowData._id.$oid;
                    }
                }
                window.location = location;
            });
        }

        return this;
    };

    /**
     * Factory to create new table elements.
     *
     * @param {object} settings: The settings associated with the table.
    **/
    gTable = function(settings) {
        var key,
            newTable;

        newTable = Object.create(kciTable);

        if (settings) {
            for (key in settings) {
                if (settings.hasOwnProperty(key)) {
                    newTable[key] = settings[key];
                }
            }
        } else {
            throw 'No settings found';
        }

        return newTable.setup();
    };

    return gTable;
});
<|endoftext|>


<commit_before>import {
  AUTH_USER,
  SET_USER_DATA,
  UNAUTH_USER,
  AUTH_ERROR,
  SET_CREDIT_CARDS,
  SET_DEFAULT_CARD
} from '../constants/';

import {
  resetSession,
  setSession,
  getSession
} from '../utils/api/header-config';

export const authUser = () => ({ type: AUTH_USER });
export const setUserData = (user) => ({ type: SET_USER_DATA, payload: user });
export const authError = (error) => ({ type: AUTH_ERROR, payload: error });
export const unauthUser = () => ({ type: UNAUTH_USER });
export const setCreditCards = (cards) => ({type: SET_CREDIT_CARDS, payload: cards});
export const setDefaultCard = (card) => ({ type: SET_DEFAULT_CARD, payload: card });
export const addCreditCard = (card) => ({ type: ADD_CREDIT_CARD, payload: card });

// Async actions

export const signupUser = (email, password) => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signup(email, password).request
      .then(response => {
        console.log('signup user successfully', response);
        dispatch(authUser());
        dispatch(setUserData(response.data.user));
        setSession(response.data.user, response.data.session);
      })
      .catch( error => {
        console.log('error to signup user', error.response);
        dispatch(authError(error.response.data.error.user));
      });
  }
};

export const signinUser = (email, password) => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signin(email, password).request
      .then(response => {
        console.log('signin user successfully', response);
        dispatch(authUser());
        dispatch(setUserData(response.data.user));
        if (response.data.cards.length > 0) {
          dispatch(setCreditCards(response.data.cards));
          const defaultCard = response.data.cards.filter(card => card.default);
          dispatch(setDefaultCard(defaultCard));
        }
        setSession(response.data.user, response.data.session);
      })
      .catch(error => {
        console.log('error to signin user', error.response);
        // dispatch(authError(error.response.error.user));
      })
  }
};

export const signoutUser = () => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signout().request
      .then(response => {
        console.log('signout user successfully', response);
        dispatch(unauthUser())
        resetSession();
      })
      .catch(error => {
        console.log('error to signout user', error.response);
        dispatch(authError(error.response.error.user));
      })
  }
};

<commit_msg>Add getCards async-action for auth<commit_after>import {
  AUTH_USER,
  SET_USER_DATA,
  UNAUTH_USER,
  AUTH_ERROR,
  SET_CREDIT_CARDS,
  SET_DEFAULT_CARD
} from '../constants/';

import {
  resetSession,
  setSession,
  getSession
} from '../utils/api/header-config';

export const authUser = () => ({ type: AUTH_USER });
export const setUserData = (user) => ({ type: SET_USER_DATA, payload: user });
export const authError = (error) => ({ type: AUTH_ERROR, payload: error });
export const unauthUser = () => ({ type: UNAUTH_USER });
export const setCreditCards = (cards) => ({type: SET_CREDIT_CARDS, payload: cards});
export const setDefaultCard = (card) => ({ type: SET_DEFAULT_CARD, payload: card });
export const addCreditCard = (card) => ({ type: ADD_CREDIT_CARD, payload: card });

// Async actions

export const signupUser = (email, password) => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signup(email, password).request
      .then(response => {
        console.log('signup user successfully', response);
        dispatch(authUser());
        dispatch(setUserData(response.data.user));
        setSession(response.data.user, response.data.session);
      })
      .catch( error => {
        console.log('error to signup user', error.response);
        dispatch(authError(error.response.data.error.user));
      });
  }
};

export const signinUser = (email, password) => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signin(email, password).request
      .then(response => {
        console.log('signin user successfully', response);
        dispatch(authUser());
        dispatch(setUserData(response.data.user));
        setSession(response.data.user, response.data.session);
      })
      .catch(error => {
        console.log('error to signin user', error.response);
        // dispatch(authError(error.response.error.user));
      })
  }
};

export const signoutUser = () => {
  return (dispatch, getState, { AuthAPI }) => {
    return AuthAPI.signout().request
      .then(response => {
        console.log('signout user successfully', response);
        dispatch(unauthUser())
        resetSession();
      })
      .catch(error => {
        console.log('error to signout user', error.response);
        dispatch(authError(error.response.error.user));
      })
  }
};

export const getCreditCards = () => {
  return (dispatch, getState, { CardAPI }) => {
    return CardAPI.index().request
      .then(response => {
        console.log('get credit cards successfully', response);
        if (response.data.cards.length > 0) {
          dispatch(setCreditCards(response.data.cards));
          const defaultCard = response.data.cards.filter(card => card.default);
          dispatch(setDefaultCard(defaultCard));
        };
      })
      .catch(error => {
        console.log('error to get credit cards', error.response);
      })
  }
}<|endoftext|>


<commit_before>import React, { useState, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import { BrowserRouter as Router, Route, useParams } from 'react-router-dom'
import axios from 'axios'
import classNames from 'classnames'
// import Glide from '@glidejs/glide'
import Siema from 'siema'
import ReactMarkdown from 'react-markdown'
import PubSub from 'pubsub-js'

import { useI18n } from '../I18n'
import { useForm } from '../Form'

import Acc from './Show/Acc'
import Guide from './Show/Guide'
import Variants from './Show/Variants'
import Price from './Price'
import { path, Routes } from '../Routes'

// import form from '../Form.module.css'
import page from '../Page'
// import list from './List.module.css'
import styles from './Show.module.css'
import buttons from '../Buttons.module.css'

Show.propTypes = {
  locale: PropTypes.string.isRequired
}

export default function Show ({ locale }) {
  return (
    <Router>
      <Route path={Routes.catalog_variant_path}>
        <Variant locale={locale} />
      </Route>
    </Router>
  )
}

Variant.propTypes = {
  locale: PropTypes.string.isRequired
}

function Variant ({ locale }) {
  const { slug, id } = useParams()
  const I18n = useI18n(locale)

  const [variant, setVariant] = useState()
  const [variants, setVariants] = useState()
  const [size, setSize] = useState()
  const [preorderWarning, setPreorderWarning] = useState(false)

  const slidesRef = useRef()
  // const sliderElRef = useRef()
  const sliderRef = useRef()
  const imagesCountRef = useRef()
  const kitsCountRef = useRef()
  const kitSlidesRef = useRef()
  const kitSliderRef = useRef()

  useEffect(() => {
    const _fetch = async () => {
      const { data } = await axios.get(path('catalog_variant_path', { id, slug, format: 'json' }))

      setVariants(data.variants)
    }

    _fetch()
    window.addEventListener('resize', updateDimensions)
  }, [])

  useEffect(() => {
    if (variants) {
      if (sliderRef.current) {
        sliderRef.current.destroy(true)
        sliderRef.current = null
      }

      if (kitSliderRef.current) {
        kitSliderRef.current.destroy(true)
        kitSliderRef.current = null
      }

      setVariant(variants.find(v => v.id === parseInt(id)))
      if (variants.find(v => v.id === parseInt(id)).kits) {
        setSection('kits')
      }
    }
  }, [variants, id])

  useEffect(() => {
    if (variant) {
      imagesCountRef.current = variant.images.length

      if (variant.kits) {
        kitsCountRef.current = variant.kits.length
      }

      updateDimensions()
      if (variant.availabilities.length === 1 && variant.availabilities[0].size.id === 1 && variant.availabilities[0].active) {
        setSize(variant.availabilities[0].size)
      } else {
        setSize()
      }
      setNoSize(false)

      // PubSub.publish('notification-cart', variant)
    }
  }, [variant])

  const updateDimensions = () => {
    if (slidesRef.current && window.getComputedStyle(slidesRef.current).getPropertyValue('position') === 'static') {
      if (!sliderRef.current && imagesCountRef.current > 1) {
        sliderRef.current = new Siema({
          selector: slidesRef.current
        })
      }
    } else if (sliderRef.current) {
      sliderRef.current.destroy(true)
      sliderRef.current = null
    }

    if (kitSlidesRef.current) {
      if (kitSliderRef.current) {
        kitSliderRef.current.destroy(true)
        kitSliderRef.current = null
      }

      if (!kitSliderRef.current && kitsCountRef.current > 1) {
        kitSliderRef.current = new Siema({
          selector: kitSlidesRef.current
        })
      }
    }
  }

  const [section, setSection] = useState()

  const toggleSection = newSection => {
    setSection(section === newSection ? null : newSection)
  }

  const {
    pending,
    onSubmit,
    cancelToken
  } = useForm()

  const [noSize, setNoSize] = useState(false)

  const handleCartClick = async e => {
    // e.preventDefault()

    if (!size) {
      setNoSize(true)
      return
    }

    setNoSize(false)

    await axios.post(
      path('cart_variant_path', { id: variant.id, format: 'json' }),
      {
        size: size.id
      },
      { cancelToken: cancelToken.current.token }
    ).then(res => {
      setSize()
      setPreorderWarning(false)
      PubSub.publish('update-cart', res.data.quantity)
      PubSub.publish('notification-cart', variant)
    }).catch(_error => {
    })
  }

  return (

      {variant && variants &&

            {variant.images.length > 0 &&

                {variant.images.map(image =>

                )}

            }

            {variant.images.length < 1 &&

            }

            {/* {variant.images.length > 1 &&

{index}/{variant.images.length}

            } */}

            {variant.label &&

                {I18n.t(`variant.labels.${variant.label}`)}

            }

                {variant.title}

              {variant.can_edit &&

                    Редактировать

                    Размеры и количество

                  <a href={path('new_variant_path') + `?product_id=${variant.product.id}`}>
                    Добавить цвет

              }

              <Price sell={parseFloat(variant.price_sell)} origin={parseFloat(variant.price)} originClass={styles.origin} sellClass={styles.sell} />

            <Variants variants={variants} variant={variant} className={styles.variants} />

            {variant.availabilities.filter(a => a.active || variant.preorder).length > 0 &&
              <>

                    {variant.availabilities.map(availability =>
                      <div
                        key={availability.size.id}
                        className={classNames(
                          styles.size,
                          styles[`size_${availability.size.id}`],
                          { [styles.unavailable]: (!availability.active && !variant.preorder), [styles.active]: size && availability.size.id === size.id }
                        )}
                        onClick={() => {
                          if (availability.active || variant.preorder) {
                            setSize(availability.size)
                            setPreorderWarning(!availability.active)
                          }
                        }}
                      >
                        {availability.size.title}

                    )}

                  {preorderWarning &&

                      {I18n.t('variant.preorder')}

                  }

                    <Guide locale={locale} />

                    <button
                      className={classNames(buttons.main, { [buttons.pending]: pending })}
                      disabled={pending}
                      onClick={onSubmit(handleCartClick)}
                    >
                      {pending ? I18n.t('variant.cart.adding') : I18n.t('variant.cart.add')}
                    </button>

                    {noSize &&

{I18n.t('variant.size.select')}

                    }

              </>
            }

            {variant.desc &&

                <ReactMarkdown source={variant.desc} />

            }

            {variant.kits &&
              <Acc id="kits" title={I18n.t('variant.kits')} onToggle={toggleSection} section={section}>

                    {variant.kits.map((kit, i) =>

{I18n.t('kit_variants', { count: kit.items })}

                          {I18n.t('variant.more')}

                    )}

              </Acc>
            }

            {variant.comp &&
              <Acc id="desc" title={I18n.t('variant.comp')} onToggle={toggleSection} section={section}>
                <ReactMarkdown source={variant.comp} />
              </Acc>
            }

            <Acc id="delivery" title={I18n.t('variant.delivery.title')} onToggle={toggleSection} section={section}>

                {I18n.t('variant.delivery.russia')}

                {I18n.t('variant.delivery.world')}

                {I18n.t('variant.more')}

            </Acc>

            <Acc id="return" title={I18n.t('variant.return.title')} onToggle={toggleSection} section={section}>

                {I18n.t('variant.return.desc')}

                {I18n.t('variant.more')}

            </Acc>

      }

  )
}
<commit_msg>Автовыбор One Size для предзаказа<commit_after>import React, { useState, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import { BrowserRouter as Router, Route, useParams } from 'react-router-dom'
import axios from 'axios'
import classNames from 'classnames'
// import Glide from '@glidejs/glide'
import Siema from 'siema'
import ReactMarkdown from 'react-markdown'
import PubSub from 'pubsub-js'

import { useI18n } from '../I18n'
import { useForm } from '../Form'

import Acc from './Show/Acc'
import Guide from './Show/Guide'
import Variants from './Show/Variants'
import Price from './Price'
import { path, Routes } from '../Routes'

// import form from '../Form.module.css'
import page from '../Page'
// import list from './List.module.css'
import styles from './Show.module.css'
import buttons from '../Buttons.module.css'

Show.propTypes = {
  locale: PropTypes.string.isRequired
}

export default function Show ({ locale }) {
  return (
    <Router>
      <Route path={Routes.catalog_variant_path}>
        <Variant locale={locale} />
      </Route>
    </Router>
  )
}

Variant.propTypes = {
  locale: PropTypes.string.isRequired
}

function Variant ({ locale }) {
  const { slug, id } = useParams()
  const I18n = useI18n(locale)

  const [variant, setVariant] = useState()
  const [variants, setVariants] = useState()
  const [size, setSize] = useState()
  const [preorderWarning, setPreorderWarning] = useState(false)

  const slidesRef = useRef()
  // const sliderElRef = useRef()
  const sliderRef = useRef()
  const imagesCountRef = useRef()
  const kitsCountRef = useRef()
  const kitSlidesRef = useRef()
  const kitSliderRef = useRef()

  useEffect(() => {
    const _fetch = async () => {
      const { data } = await axios.get(path('catalog_variant_path', { id, slug, format: 'json' }))

      setVariants(data.variants)
    }

    _fetch()
    window.addEventListener('resize', updateDimensions)
  }, [])

  useEffect(() => {
    if (variants) {
      if (sliderRef.current) {
        sliderRef.current.destroy(true)
        sliderRef.current = null
      }

      if (kitSliderRef.current) {
        kitSliderRef.current.destroy(true)
        kitSliderRef.current = null
      }

      setVariant(variants.find(v => v.id === parseInt(id)))
      if (variants.find(v => v.id === parseInt(id)).kits) {
        setSection('kits')
      }
    }
  }, [variants, id])

  useEffect(() => {
    if (variant) {
      imagesCountRef.current = variant.images.length

      if (variant.kits) {
        kitsCountRef.current = variant.kits.length
      }

      updateDimensions()
      if (variant.availabilities.length === 1 && variant.availabilities[0].size.id === 1) {
        if (variant.availabilities[0].active || variant.preorder) {
          setSize(variant.availabilities[0].size)
          setPreorderWarning(!variant.availabilities[0].active)
        }
      } else {
        setSize()
      }
      setNoSize(false)

      // PubSub.publish('notification-cart', variant)
    }
  }, [variant])

  const updateDimensions = () => {
    if (slidesRef.current && window.getComputedStyle(slidesRef.current).getPropertyValue('position') === 'static') {
      if (!sliderRef.current && imagesCountRef.current > 1) {
        sliderRef.current = new Siema({
          selector: slidesRef.current
        })
      }
    } else if (sliderRef.current) {
      sliderRef.current.destroy(true)
      sliderRef.current = null
    }

    if (kitSlidesRef.current) {
      if (kitSliderRef.current) {
        kitSliderRef.current.destroy(true)
        kitSliderRef.current = null
      }

      if (!kitSliderRef.current && kitsCountRef.current > 1) {
        kitSliderRef.current = new Siema({
          selector: kitSlidesRef.current
        })
      }
    }
  }

  const [section, setSection] = useState()

  const toggleSection = newSection => {
    setSection(section === newSection ? null : newSection)
  }

  const {
    pending,
    onSubmit,
    cancelToken
  } = useForm()

  const [noSize, setNoSize] = useState(false)

  const handleCartClick = async e => {
    // e.preventDefault()

    if (!size) {
      setNoSize(true)
      return
    }

    setNoSize(false)

    await axios.post(
      path('cart_variant_path', { id: variant.id, format: 'json' }),
      {
        size: size.id
      },
      { cancelToken: cancelToken.current.token }
    ).then(res => {
      setSize()
      setPreorderWarning(false)
      PubSub.publish('update-cart', res.data.quantity)
      PubSub.publish('notification-cart', variant)
    }).catch(_error => {
    })
  }

  return (

      {variant && variants &&

            {variant.images.length > 0 &&

                {variant.images.map(image =>

                )}

            }

            {variant.images.length < 1 &&

            }

            {/* {variant.images.length > 1 &&

{index}/{variant.images.length}

            } */}

            {variant.label &&

                {I18n.t(`variant.labels.${variant.label}`)}

            }

                {variant.title}

              {variant.can_edit &&

                    Редактировать

                    Размеры и количество

                  <a href={path('new_variant_path') + `?product_id=${variant.product.id}`}>
                    Добавить цвет

              }

              <Price sell={parseFloat(variant.price_sell)} origin={parseFloat(variant.price)} originClass={styles.origin} sellClass={styles.sell} />

            <Variants variants={variants} variant={variant} className={styles.variants} />

            {variant.availabilities.filter(a => a.active || variant.preorder).length > 0 &&
              <>

                    {variant.availabilities.map(availability =>
                      <div
                        key={availability.size.id}
                        className={classNames(
                          styles.size,
                          styles[`size_${availability.size.id}`],
                          { [styles.unavailable]: (!availability.active && !variant.preorder), [styles.active]: size && availability.size.id === size.id }
                        )}
                        onClick={() => {
                          if (availability.active || variant.preorder) {
                            setSize(availability.size)
                            setPreorderWarning(!availability.active)
                          }
                        }}
                      >
                        {availability.size.title}

                    )}

                  {preorderWarning &&

                      {I18n.t('variant.preorder')}

                  }

                    <Guide locale={locale} />

                    <button
                      className={classNames(buttons.main, { [buttons.pending]: pending })}
                      disabled={pending}
                      onClick={onSubmit(handleCartClick)}
                    >
                      {pending ? I18n.t('variant.cart.adding') : I18n.t('variant.cart.add')}
                    </button>

                    {noSize &&

{I18n.t('variant.size.select')}

                    }

              </>
            }

            {variant.desc &&

                <ReactMarkdown source={variant.desc} />

            }

            {variant.kits &&
              <Acc id="kits" title={I18n.t('variant.kits')} onToggle={toggleSection} section={section}>

                    {variant.kits.map((kit, i) =>

{I18n.t('kit_variants', { count: kit.items })}

                          {I18n.t('variant.more')}

                    )}

              </Acc>
            }

            {variant.comp &&
              <Acc id="desc" title={I18n.t('variant.comp')} onToggle={toggleSection} section={section}>
                <ReactMarkdown source={variant.comp} />
              </Acc>
            }

            <Acc id="delivery" title={I18n.t('variant.delivery.title')} onToggle={toggleSection} section={section}>

                {I18n.t('variant.delivery.russia')}

                {I18n.t('variant.delivery.world')}

                {I18n.t('variant.more')}

            </Acc>

            <Acc id="return" title={I18n.t('variant.return.title')} onToggle={toggleSection} section={section}>

                {I18n.t('variant.return.desc')}

                {I18n.t('variant.more')}

            </Acc>

      }

  )
}
<|endoftext|>


<commit_before>// @flow

import React, { Component } from 'react';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
import { capitalize, sumBy } from 'lodash';
import { ProfilePicture, CircularPicture } from 'app/components/Image';
import Card from 'app/components/Card';
import Pill from 'app/components/Pill';
import LoadingIndicator from 'app/components/LoadingIndicator';
import Feed from 'app/components/Feed';
import Penalties from './Penalties';
import styles from './UserProfile.css';
import { Flex } from 'app/components/Layout';
import Tooltip from 'app/components/Tooltip';
import { groupBy } from 'lodash';
import { resolveGroupLink } from 'app/reducers/groups';
import type { Group } from 'app/models';
import cx from 'classnames';
import { EventItem } from 'app/routes/events/components/EventList';
import EmptyState from 'app/components/EmptyState';

const fieldTranslations = {
  username: 'brukernavn',
  email: 'e-post'
};

type Props = {
  user: any,
  showSettings: boolean,
  feedItems: Array<any>,
  feed: Object,
  isMe: Boolean,
  upcomingEvents: Array<any>
};

const GroupPill = ({ group }: { group: Group }) => (
  <Pill key={group.id} style={{ margin: '5px' }}>
    {group.name}
  </Pill>
);

const GroupBadge = ({ group }: { group: Group }) => {
  const groupElement = (
    <Tooltip key={group.id} content={group.name}>
      <CircularPicture
        alt={group.name}
        src={group.logo}
        size={50}
        style={{ margin: '10px 5px' }}
      />
    </Tooltip>
  );
  const link = resolveGroupLink(group);
  if (!link) {
    return groupElement;
  }
  return (
    <Link key={group.id} to={resolveGroupLink(group)}>
      {groupElement}
    </Link>
  );
};

const UpcomingEvents = ({ events }: Props) => (

    {events.length ? (
      <Flex column wrap>
        {events.map((event, i) => (
          <EventItem key={i} event={event} showTags={false} />
        ))}
      </Flex>
    ) : (
      <EmptyState>

          Du har ingen kommende arrangementer

      </EmptyState>
    )}

);

export default class UserProfile extends Component<Props> {
  sumPenalties() {
    return sumBy(this.props.user.penalties, 'weight');
  }

  renderFields() {
    const { user } = this.props;
    const fields = Object.keys(fieldTranslations).filter(field => user[field]);
    const tags = fields.map(field => {
      const translation = capitalize(fieldTranslations[field]);
      return (

          {translation}: {user[field]}

      );
    });

    return
{tags}
;
  }

  render() {
    const {
      user,
      isMe,
      showSettings,
      feedItems,
      feed,
      upcomingEvents
    } = this.props;
    const { groupsAsBadges = [], groupsAsPills = [] } = groupBy(
      user.abakusGroups,
      group => (group.logo ? 'groupsAsBadges' : 'groupsAsPills')
    );
    return (

        <Helmet title={`${user.firstName} ${user.lastName}`} />

        <Flex wrap className={styles.header}>

            <ProfilePicture user={user} size={150} />

          <Flex column className={styles.rightContent}>

{user.fullName}

            <Flex wrap>
              {groupsAsPills.map(group => (
                <GroupPill key={group.id} group={group} />
              ))}
            </Flex>
            <Flex>
              {groupsAsBadges.map(group => (
                <GroupBadge group={group} key={group.id} />
              ))}
            </Flex>
          </Flex>
        </Flex>

        <Flex wrap className={styles.content}>

Brukerinfo

              <Card className={styles.infoCard}>
                {this.renderFields()}
                {showSettings ? (
                  <Link to={`/users/${user.username}/settings/profile`}>
                    Innstillinger
                  </Link>
                ) : (
                  ''
                )}
              </Card>

            {showSettings && (

Prikker ({this.sumPenalties()} stk)

                <Card className={styles.infoCard}>
                  <Penalties penalties={user.penalties} />
                </Card>

            )}

            {isMe &&
              user.email !== user.emailAddress && (

Google GSuite

                  <Card className={styles.infoCard}>

                      Din konto er linket opp mot Abakus sitt domene i Google
                      GSuite. E-post sendes til denne brukeren og ikke til
                      e-posten du har oppgitt i din profil.

                        URL:{' '}
                        mail.abakus.no

                        E-post: {user.emailAddress}

                        Passord: Ditt abakus passord

                  </Card>

              )}

            {isMe && (

Dine kommende arrangementer

                {upcomingEvents ? (
                  <UpcomingEvents events={upcomingEvents} />
                ) : (
                  <LoadingIndicator loading />
                )}

            )}

Nylig Aktivitet

            {feed ? (
              <Feed items={feedItems} feed={feed} />
            ) : (
              <LoadingIndicator loading />
            )}

        </Flex>

    );
  }
}
<commit_msg>Fix linting error<commit_after>// @flow

import React, { Component } from 'react';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
import { capitalize, sumBy } from 'lodash';
import { ProfilePicture, CircularPicture } from 'app/components/Image';
import Card from 'app/components/Card';
import Pill from 'app/components/Pill';
import LoadingIndicator from 'app/components/LoadingIndicator';
import Feed from 'app/components/Feed';
import Penalties from './Penalties';
import styles from './UserProfile.css';
import { Flex } from 'app/components/Layout';
import Tooltip from 'app/components/Tooltip';
import { groupBy } from 'lodash';
import { resolveGroupLink } from 'app/reducers/groups';
import type { Group } from 'app/models';
import cx from 'classnames';
import { EventItem } from 'app/routes/events/components/EventList';
import EmptyState from 'app/components/EmptyState';

const fieldTranslations = {
  username: 'brukernavn',
  email: 'e-post'
};

type Props = {
  user: any,
  showSettings: boolean,
  feedItems: Array<any>,
  feed: Object,
  isMe: Boolean,
  upcomingEvents: Array<any>
};

const GroupPill = ({ group }: { group: Group }) => (
  <Pill key={group.id} style={{ margin: '5px' }}>
    {group.name}
  </Pill>
);

const GroupBadge = ({ group }: { group: Group }) => {
  const groupElement = (
    <Tooltip key={group.id} content={group.name}>
      <CircularPicture
        alt={group.name}
        src={group.logo}
        size={50}
        style={{ margin: '10px 5px' }}
      />
    </Tooltip>
  );
  const link = resolveGroupLink(group);
  if (!link) {
    return groupElement;
  }
  return (
    <Link key={group.id} to={resolveGroupLink(group)}>
      {groupElement}
    </Link>
  );
};

const UpcomingEvents = ({ upcomingEvents }: Props) => (

    {upcomingEvents.length ? (
      <Flex column wrap>
        {upcomingEvents.map((event, i) => (
          <EventItem key={i} event={event} showTags={false} />
        ))}
      </Flex>
    ) : (
      <EmptyState>

          Du har ingen kommende arrangementer

      </EmptyState>
    )}

);

export default class UserProfile extends Component<Props> {
  sumPenalties() {
    return sumBy(this.props.user.penalties, 'weight');
  }

  renderFields() {
    const { user } = this.props;
    const fields = Object.keys(fieldTranslations).filter(field => user[field]);
    const tags = fields.map(field => {
      const translation = capitalize(fieldTranslations[field]);
      return (

          {translation}: {user[field]}

      );
    });

    return
{tags}
;
  }

  render() {
    const {
      user,
      isMe,
      showSettings,
      feedItems,
      feed,
      upcomingEvents
    } = this.props;
    const { groupsAsBadges = [], groupsAsPills = [] } = groupBy(
      user.abakusGroups,
      group => (group.logo ? 'groupsAsBadges' : 'groupsAsPills')
    );
    return (

        <Helmet title={`${user.firstName} ${user.lastName}`} />

        <Flex wrap className={styles.header}>

            <ProfilePicture user={user} size={150} />

          <Flex column className={styles.rightContent}>

{user.fullName}

            <Flex wrap>
              {groupsAsPills.map(group => (
                <GroupPill key={group.id} group={group} />
              ))}
            </Flex>
            <Flex>
              {groupsAsBadges.map(group => (
                <GroupBadge group={group} key={group.id} />
              ))}
            </Flex>
          </Flex>
        </Flex>

        <Flex wrap className={styles.content}>

Brukerinfo

              <Card className={styles.infoCard}>
                {this.renderFields()}
                {showSettings ? (
                  <Link to={`/users/${user.username}/settings/profile`}>
                    Innstillinger
                  </Link>
                ) : (
                  ''
                )}
              </Card>

            {showSettings && (

Prikker ({this.sumPenalties()} stk)

                <Card className={styles.infoCard}>
                  <Penalties penalties={user.penalties} />
                </Card>

            )}

            {isMe &&
              user.email !== user.emailAddress && (

Google GSuite

                  <Card className={styles.infoCard}>

                      Din konto er linket opp mot Abakus sitt domene i Google
                      GSuite. E-post sendes til denne brukeren og ikke til
                      e-posten du har oppgitt i din profil.

                        URL:{' '}
                        mail.abakus.no

                        E-post: {user.emailAddress}

                        Passord: Ditt abakus passord

                  </Card>

              )}

            {isMe && (

Dine kommende arrangementer

                {upcomingEvents ? (
                  <UpcomingEvents events={upcomingEvents} />
                ) : (
                  <LoadingIndicator loading />
                )}

            )}

Nylig Aktivitet

            {feed ? (
              <Feed items={feedItems} feed={feed} />
            ) : (
              <LoadingIndicator loading />
            )}

        </Flex>

    );
  }
}
<|endoftext|>


<commit_before>var Chart = require('../../../lib/time-series-chart');
var utils = require('../../../lib/utils');

module.exports = Vue.extend({
  template: require('./template')(),
  timer: null,

  created: function () {
    this.$watch('refresh', this.timer.bind(this));
  },

  ready: function () {
    var dom = this.$el.querySelector('.chart');
    this.chart = Chart.create(dom, this.$data);
    this.tick();

    this.$on('update', function (dashboard) {
      this.tick();
    });

    this.$id = uuid.v1();
  },

  beforeDestroy: function () {
    this.stopTimer();
  },

  methods: {
    editPanel: function () {
      $('.collapse', this.$el).collapse('toggle');
    },

    deletePanel: function () {
      if (window.confirm(this.deleteConfirmationMessage)) {
        this.$dispatch('delete-panel', this);
      }
    },

    onError: function (xhr, textStatus, error) {
      this.chart.error(xhr.status + ':' + xhr.statusText);
    },

    timer: function (enable) {
      return enable ? this.startTimer() : this.stopTimer();
    },

    startTimer: function () {
      var self = this;
      this.stopTimer();
      this.$options.timer = setTimeout(function tf() {
        self.tick();
        if (self.refresh) {
          self.$options.timer = setTimeout(tf, utils.milisec(self.interval));
        }
      }, utils.milisec(this.interval));
      self.tick();
    },

    stopTimer: function () {
      if (this.$options.timer) {
        clearTimeout(this.$options.timer);
        this.$options.intervalTimer = null;
      }
    },

    tick: function () {
      var self = this;
      this.chart.prepareUpdate(this);
      if (_.isEmpty(this.query)) {
        Vue.nextTick(function () {
          self.chart.error('Query is empty');
        });
      } else {
        var refresh = $('.refresh', this.$el);
        refresh.addClass('rotate');

        influxdb
          .query(this.fullQuery)
          .done(function (data) {
            Vue.nextTick(function () {
              self.chart.update(data);
            });
          })
          .fail(this.onError.bind(this))
          .always(function () {
            refresh.removeClass('rotate');
          });
      }
    }
  },

  computed: {
    fullQuery: function () {
      var dashboard = this.$root.dashboard;
      return this.query + ' where time > ' + dashboard.from + ' and time < ' + dashboard.to + ' order asc';
    },

    deleteConfirmationMessage: function () {
      return 'Are you sure you want to remove this "' + this.title + '" panel?';
    }
  }
});
<commit_msg>Changed to removed ';' in panel's input query.<commit_after>var Chart = require('../../../lib/time-series-chart');
var utils = require('../../../lib/utils');

module.exports = Vue.extend({
  template: require('./template')(),
  timer: null,

  created: function () {
    this.$watch('refresh', this.timer.bind(this));
  },

  ready: function () {
    var dom = this.$el.querySelector('.chart');
    this.chart = Chart.create(dom, this.$data);
    this.tick();

    this.$on('update', function (dashboard) {
      this.tick();
    });

    this.$id = uuid.v1();
  },

  beforeDestroy: function () {
    this.stopTimer();
  },

  methods: {
    editPanel: function () {
      $('.collapse', this.$el).collapse('toggle');
    },

    deletePanel: function () {
      if (window.confirm(this.deleteConfirmationMessage)) {
        this.$dispatch('delete-panel', this);
      }
    },

    onError: function (xhr, textStatus, error) {
      this.chart.error(xhr.status + ':' + xhr.statusText);
    },

    timer: function (enable) {
      return enable ? this.startTimer() : this.stopTimer();
    },

    startTimer: function () {
      var self = this;
      this.stopTimer();
      this.$options.timer = setTimeout(function tf() {
        self.tick();
        if (self.refresh) {
          self.$options.timer = setTimeout(tf, utils.milisec(self.interval));
        }
      }, utils.milisec(this.interval));
      self.tick();
    },

    stopTimer: function () {
      if (this.$options.timer) {
        clearTimeout(this.$options.timer);
        this.$options.intervalTimer = null;
      }
    },

    tick: function () {
      var self = this;
      this.chart.prepareUpdate(this);
      if (_.isEmpty(this.query)) {
        Vue.nextTick(function () {
          self.chart.error('Query is empty');
        });
      } else {
        var refresh = $('.refresh', this.$el);
        refresh.addClass('rotate');

        influxdb
          .query(this.fullQuery)
          .done(function (data) {
            Vue.nextTick(function () {
              self.chart.update(data);
            });
          })
          .fail(this.onError.bind(this))
          .always(function () {
            refresh.removeClass('rotate');
          });
      }
    }
  },

  computed: {
    fullQuery: function () {
      var dashboard = this.$root.dashboard;
      return this.query.replace(/;\s*$/, '') + ' where time > ' + dashboard.from + ' and time < ' + dashboard.to + ' order asc';
    },

    deleteConfirmationMessage: function () {
      return 'Are you sure you want to remove this "' + this.title + '" panel?';
    }
  }
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Formsy from 'formsy-react';
import FRC from 'formsy-react-components';
import reduce from 'lodash.reduce';
import get from 'lodash.get';
import isEmpty from 'lodash.isempty';

import 'react-select/dist/react-select.css';
import { Modal } from '../../components/Modal';

const { Input, Textarea, Select } = FRC;

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

    this.submitForm = this.submitForm.bind(this);
  }

  submitForm() {
    const myform = this.myform.getModel();
    const institution = {
      name: myform.name,
      address: myform.institutionAddress,
      area: myform.institutionArea,
      landmark: myform.institutionLandmark,
      pincode: myform.institutionPincode,
      institution_languages: myform.institutionLang,
      admin3: this.props.parent,
      gender: myform.institutionGender,
      category: myform.institutionCat,
      management: myform.institutionManagement,
      last_verified_year: myform.last_verified_year,
      status: 'AC',
      dise: myform.institutionDise_code,
    };

    const filterInstitution = reduce(
      institution,
      (soFar, value, key) => {
        if (value) {
          soFar[key] = value;
        }
        return soFar;
      },
      {},
    );

    this.props.save(filterInstitution);
  }

  render() {
    const {
      title,
      isOpen,
      placeHolder,
      languages,
      managements,
      institutionCategories,
      lastVerifiedYears,
      error,
    } = this.props;

    const selectOptions = [
      { value: 'co-ed', label: 'Co-Ed' },
      { value: 'boys', label: 'Boys' },
      { value: 'girls', label: 'Girls' },
    ];

    return (
      <Modal
        title={title}
        contentLabel={title}
        isOpen={isOpen}
        onCloseModal={this.props.closeConfirmModal}
        canSubmit={this.props.canSubmit}
        submitForm={this.submitForm}
      >
        <Formsy.Form
          onValidSubmit={this.submitForm}
          onValid={this.props.enableSubmitForm}
          onInvalid={this.props.disableSubmitForm}
          ref={(ref) => {
            this.myform = ref;
          }}
        >
          {!isEmpty(error) ? (

              {Object.keys(error).map((key) => {
                const value = error[key];
                return (

                    {key}: {value[0]}

                );
              })}

          ) : (

          )}
          <Input
            name="name"
            id="name"
            value=""
            label="School Name:"
            type="text"
            placeholder={placeHolder}
            required
            validations="minLength:1"
          />
          <Textarea
            rows={3}
            cols={40}
            name="institutionAddress"
            label="Address :"
            value=""
            required
            validations="minLength:1"
          />
          <Input
            name="institutionArea"
            id="institutionArea"
            label="Area:"
            type="text"
            value=""
            className="form-control"
          />
          <Input
            name="institutionLandmark"
            id="institutionLandmark"
            label="Landmark:"
            type="text"
            value=""
            className="form-control"
          />
          <Input
            name="institutionPincode"
            id="institutionPincode"
            label="Pincode:"
            type="text"
            value=""
            className="form-control"
          />
          <Select
            name="institutionCat"
            label="Category:"
            value={get(institutionCategories[0], 'value')}
            options={institutionCategories}
          />
          <Select
            multiple
            name="institutionLang"
            label="Medium:"
            value={[get(languages[0], 'value')]}
            options={languages}
            required
          />
          <Select
            name="institutionManagement"
            label="Management:"
            value={get(managements[0], 'value')}
            options={managements}
            required
          />
          <Select
            name="institutionGender"
            label="Gender:"
            value={get(selectOptions, '[0].value')}
            options={selectOptions}
            required
          />
          <Input
            name="institutionDise_code"
            id="institutionDise_code"
            value=""
            label="DISE Code:"
            type="text"
            className="form-control"
            validations="isLength:11"
            required
          />
          <Select
            name="last_verified_year"
            label="Last Verified Year:"
            value={get(lastVerifiedYears[0], 'value')}
            options={lastVerifiedYears}
            required
          />
        </Formsy.Form>
      </Modal>
    );
  }
}

CreateInstitutionForm.propTypes = {
  error: PropTypes.object,
  isOpen: PropTypes.bool,
  canSubmit: PropTypes.bool,
  title: PropTypes.string,
  placeHolder: PropTypes.string,
  parent: PropTypes.number,
  languages: PropTypes.array,
  managements: PropTypes.array,
  lastVerifiedYears: PropTypes.array,
  institutionCategories: PropTypes.array,
  save: PropTypes.func,
  enableSubmitForm: PropTypes.func,
  disableSubmitForm: PropTypes.func,
  closeConfirmModal: PropTypes.func,
};

export { CreateInstitutionForm };
<commit_msg>fix: Management field in Creation of new institution should be ordered alphabetically and Department of Education should be the default selected value.<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Formsy from 'formsy-react';
import FRC from 'formsy-react-components';
import reduce from 'lodash.reduce';
import get from 'lodash.get';
import isEmpty from 'lodash.isempty';

import 'react-select/dist/react-select.css';
import { Modal } from '../../components/Modal';

const { Input, Textarea, Select } = FRC;

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

    this.submitForm = this.submitForm.bind(this);
  }

  submitForm() {
    const myform = this.myform.getModel();
    const institution = {
      name: myform.name,
      address: myform.institutionAddress,
      area: myform.institutionArea,
      landmark: myform.institutionLandmark,
      pincode: myform.institutionPincode,
      institution_languages: myform.institutionLang,
      admin3: this.props.parent,
      gender: myform.institutionGender,
      category: myform.institutionCat,
      management: myform.institutionManagement,
      last_verified_year: myform.last_verified_year,
      status: 'AC',
      dise: myform.institutionDise_code,
    };

    const filterInstitution = reduce(
      institution,
      (soFar, value, key) => {
        if (value) {
          soFar[key] = value;
        }
        return soFar;
      },
      {},
    );

    this.props.save(filterInstitution);
  }

  render() {
    const {
      title,
      isOpen,
      placeHolder,
      languages,
      managements,
      institutionCategories,
      lastVerifiedYears,
      error,
    } = this.props;

    const selectOptions = [
      { value: 'co-ed', label: 'Co-Ed' },
      { value: 'boys', label: 'Boys' },
      { value: 'girls', label: 'Girls' },
    ];

    return (
      <Modal
        title={title}
        contentLabel={title}
        isOpen={isOpen}
        onCloseModal={this.props.closeConfirmModal}
        canSubmit={this.props.canSubmit}
        submitForm={this.submitForm}
      >
        <Formsy.Form
          onValidSubmit={this.submitForm}
          onValid={this.props.enableSubmitForm}
          onInvalid={this.props.disableSubmitForm}
          ref={(ref) => {
            this.myform = ref;
          }}
        >
          {!isEmpty(error) ? (

              {Object.keys(error).map((key) => {
                const value = error[key];
                return (

                    {key}: {value[0]}

                );
              })}

          ) : (

          )}
          <Input
            name="name"
            id="name"
            value=""
            label="School Name:"
            type="text"
            placeholder={placeHolder}
            required
            validations="minLength:1"
          />
          <Textarea
            rows={3}
            cols={40}
            name="institutionAddress"
            label="Address :"
            value=""
            required
            validations="minLength:1"
          />
          <Input
            name="institutionArea"
            id="institutionArea"
            label="Area:"
            type="text"
            value=""
            className="form-control"
          />
          <Input
            name="institutionLandmark"
            id="institutionLandmark"
            label="Landmark:"
            type="text"
            value=""
            className="form-control"
          />
          <Input
            name="institutionPincode"
            id="institutionPincode"
            label="Pincode:"
            type="text"
            value=""
            className="form-control"
          />
          <Select
            name="institutionCat"
            label="Category:"
            value={get(institutionCategories[0], 'value')}
            options={institutionCategories}
          />
          <Select
            multiple
            name="institutionLang"
            label="Medium:"
            value={[get(languages[0], 'value')]}
            options={languages}
            required
          />
          <Select
            name="institutionManagement"
            label="Management:"
            value={'1' || get(managements[0], 'value')}
            options={managements}
            required
          />
          <Select
            name="institutionGender"
            label="Gender:"
            value={get(selectOptions, '[0].value')}
            options={selectOptions}
            required
          />
          <Input
            name="institutionDise_code"
            id="institutionDise_code"
            value=""
            label="DISE Code:"
            type="text"
            className="form-control"
            validations="isLength:11"
            required
          />
          <Select
            name="last_verified_year"
            label="Last Verified Year:"
            value={get(lastVerifiedYears[0], 'value')}
            options={lastVerifiedYears}
            required
          />
        </Formsy.Form>
      </Modal>
    );
  }
}

CreateInstitutionForm.propTypes = {
  error: PropTypes.object,
  isOpen: PropTypes.bool,
  canSubmit: PropTypes.bool,
  title: PropTypes.string,
  placeHolder: PropTypes.string,
  parent: PropTypes.number,
  languages: PropTypes.array,
  managements: PropTypes.array,
  lastVerifiedYears: PropTypes.array,
  institutionCategories: PropTypes.array,
  save: PropTypes.func,
  enableSubmitForm: PropTypes.func,
  disableSubmitForm: PropTypes.func,
  closeConfirmModal: PropTypes.func,
};

export { CreateInstitutionForm };
<|endoftext|>


<commit_before>
angular.module('confRegistrationWebApp')
  .service('validateRegistrant', function validateRegistrant($window, ruleTypeConstants, $filter) {

    var blockVisibleRuleCheck = function(block, registrant, ruleType){
      var answers = registrant.answers;
      var ruleOperand = '';
      var validRuleCount = 0;
      var blockTypeSpecificRules = [];

      if (ruleType === ruleTypeConstants.SHOW_QUESTION) {
        blockTypeSpecificRules = $filter('showQuestionFilter')(block.rules);
        ruleOperand = block.content && block.content.ruleoperand ? block.content.ruleoperand : 'AND';
      } else if (ruleType === ruleTypeConstants.FORCE_SELECTION) {
        blockTypeSpecificRules = _.filter(block.rules, { 'ruleType': ruleType });
        ruleOperand = block.content && block.content.forceSelectionRuleOperand ? block.content.forceSelectionRuleOperand : 'AND';
      } else {
        if($window.Rollbar){
          $window.Rollbar.error('blockVisibleRuleCheck was called with an unknown rule type: ', ruleType);
        }
        ruleOperand = 'AND';
      }

      if($window.Rollbar && !_.isArray(blockTypeSpecificRules)) {
        $window.Rollbar.info('Block rules value in blockVisibleRuleCheck, ruleType: ' + ruleType + ', typeof: ' + typeof(blockTypeSpecificRules) + ', JSON.stringify: ' + JSON.stringify(blockTypeSpecificRules));
      }

      _.forEach(blockTypeSpecificRules, function (rule, i) {
        var answer = _.find(answers, { blockId: rule.parentBlockId });
        if (angular.isDefined(answer) && answer.value !== '') {
          var answerValue;
          var ruleValue;
          if (angular.isObject(answer.value)) {//answer of checkboxquestion will be an object
            answerValue = angular.isDefined(answer.value[rule.value]) ? answer.value[rule.value] : false;
            ruleValue = true;
          } else {
            //If string is a number, parse it as a float for numerical comparison
            answerValue = !isNaN(answer.value) ? parseFloat(answer.value) : answer.value;
            ruleValue = !isNaN(rule.value) ? parseFloat(rule.value) : rule.value;
          }

          if (rule.operator === '=' && answerValue === ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '!=' && answerValue !== ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '>' && answerValue > ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '<' && answerValue < ruleValue) {
            validRuleCount++;
          }
        }
        if ((ruleOperand === 'OR' && validRuleCount > 0) || (ruleOperand === 'AND' && validRuleCount <= i)) {
          return false; // Exit lodash foreach as we found a case which determines the whole outcome of this function
        }
      });

      return !blockTypeSpecificRules || blockTypeSpecificRules.length === 0 || // If no rules are set
        (ruleOperand === 'OR' && validRuleCount > 0) ||
        (ruleOperand === 'AND' && validRuleCount === blockTypeSpecificRules.length);
    };

    var choiceVisibleRuleCheck = function(block, choice, registrant, ruleType){
      var answers = registrant.answers;
      var ruleOperand = '';
      var validRuleCount = 0;
      var blockTypeSpecificRules = [];

      if (ruleType === ruleTypeConstants.SHOW_OPTION) {
        blockTypeSpecificRules = _.filter(block.rules, { 'ruleType': ruleType, 'blockEntityOption': choice.value });
        ruleOperand = 'OR';
      } else {
        if($window.Rollbar){
          $window.Rollbar.error('choiceVisibleRuleCheck was called with an unknown rule type: ', ruleType);
        }
        ruleOperand = 'AND';
      }

      if($window.Rollbar && !_.isArray(blockTypeSpecificRules)) {
        $window.Rollbar.info('Block rules value in blockVisibleRuleCheck, ruleType: ' + ruleType + ', typeof: ' + typeof(blockTypeSpecificRules) + ', JSON.stringify: ' + JSON.stringify(blockTypeSpecificRules));
      }

      _.forEach(blockTypeSpecificRules, function (rule, i) {
        var answer = _.find(answers, { blockId: rule.parentBlockId });
        if (angular.isDefined(answer) && answer.value !== '') {
          var answerValue;
          var ruleValue;
          if (angular.isObject(answer.value)) {//answer of checkboxquestion will be an object
            answerValue = angular.isDefined(answer.value[rule.value]) ? answer.value[rule.value] : false;
            ruleValue = true;
          } else {
            //If string is a number, parse it as a float for numerical comparison
            answerValue = !isNaN(answer.value) ? parseFloat(answer.value) : answer.value;
            ruleValue = !isNaN(rule.value) ? parseFloat(rule.value) : rule.value;
          }

          if (rule.operator === '=' && answerValue === ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '!=' && answerValue !== ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '>' && answerValue > ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '<' && answerValue < ruleValue) {
            validRuleCount++;
          }
        }
        if ((ruleOperand === 'OR' && validRuleCount > 0) || (ruleOperand === 'AND' && validRuleCount <= i)) {
          return false; // Exit lodash foreach as we found a case which determines the whole outcome of this function
        }
      });

      return !blockTypeSpecificRules || blockTypeSpecificRules.length === 0 || // If no rules are set
        (ruleOperand === 'OR' && validRuleCount > 0) ||
        (ruleOperand === 'AND' && validRuleCount === blockTypeSpecificRules.length);
    };

    var blockInRegistrantType = function(block, registrant){
      return !_.includes(block.registrantTypes, registrant.registrantTypeId);
    };

    this.blockVisible = function(block, registrant, isAdmin){
      var visible = angular.isDefined(registrant) && blockVisibleRuleCheck(block, registrant, ruleTypeConstants.SHOW_QUESTION) && blockInRegistrantType(block, registrant);
      return (block.adminOnly && !isAdmin) ? false : visible;
    };

    this.choiceVisible = function(block, choice, registrant){
      return angular.isDefined(registrant) && choiceVisibleRuleCheck(block, choice, registrant, ruleTypeConstants.SHOW_OPTION) && blockInRegistrantType(block, registrant);
    };

    this.checkboxDisable = function(block, registrant){
      return blockVisibleRuleCheck(block, registrant, ruleTypeConstants.FORCE_SELECTION);
    };

    this.validate = function(conference, registrant, page) {
      var invalidBlocks = [];
      conference = angular.copy(conference);
      var blocks = page ? _.find(conference.registrationPages, {id: page}).blocks : _.flatten(_.map(conference.registrationPages, 'blocks'));

      angular.forEach(blocks, function(block){
        if (!block.required || block.adminOnly || !blockVisibleRuleCheck(block, registrant, ruleTypeConstants.SHOW_QUESTION) || !blockInRegistrantType(block, registrant)) { return; }

        var answer = _.find(registrant.answers, { 'blockId': block.id });
        if (angular.isUndefined(answer)) {
          invalidBlocks.push(block.id);
          return;
        }
        answer = answer.value;

        switch (block.type) {
          case 'nameQuestion':
            if (_.isEmpty(answer.firstName) || _.isEmpty(answer.lastName)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'emailQuestion':
            if (_.isEmpty(answer) || _.isNull(answer.match(/^.+@.+$/))) { //Contains an @ sign surrounded by at least one character
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'numberQuestion':
            if (!_.isNumber(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'phoneQuestion':
            if (_.isNull(answer) || _.isNull(answer.match(/^(\D*\d\D*){10,15}$/))) { //Contains 10-15 digits
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'checkboxQuestion':
            if (_.isEmpty(answer) || _.isEmpty(_.pickBy(answer))) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'addressQuestion':
            if (_.isEmpty(answer.address1) || _.isEmpty(answer.city) || _.isEmpty(answer.state) || _.isEmpty(answer.zip)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          default:
            if(_.isEmpty(answer)){
              invalidBlocks.push(block.id);
              return;
            }
            break;
        }
      });

      return invalidBlocks;
    };
  });
<commit_msg>EVENT-581: Rerunning build..<commit_after>
angular.module('confRegistrationWebApp')
  .service('validateRegistrant', function validateRegistrant($window, ruleTypeConstants, $filter) {

    var blockVisibleRuleCheck = function(block, registrant, ruleType){
      var answers = registrant.answers;
      var ruleOperand = '';
      var validRuleCount = 0;
      var blockTypeSpecificRules = [];

      if (ruleType === ruleTypeConstants.SHOW_QUESTION) {
        blockTypeSpecificRules = $filter('showQuestionFilter')(block.rules);
        ruleOperand = block.content && block.content.ruleoperand ? block.content.ruleoperand : 'AND';
      } else if (ruleType === ruleTypeConstants.FORCE_SELECTION) {
        blockTypeSpecificRules = _.filter(block.rules, { 'ruleType': ruleType });
        ruleOperand = block.content && block.content.forceSelectionRuleOperand ? block.content.forceSelectionRuleOperand : 'AND';
      } else {
        if($window.Rollbar){
          $window.Rollbar.error('blockVisibleRuleCheck was called with an unknown rule type: ', ruleType);
        }
        ruleOperand = 'AND';
      }

      if($window.Rollbar && !_.isArray(blockTypeSpecificRules)) {
        $window.Rollbar.info('Block rules value in blockVisibleRuleCheck, ruleType: ' + ruleType + ', typeof: ' + typeof(blockTypeSpecificRules) + ', JSON.stringify: ' + JSON.stringify(blockTypeSpecificRules));
      }

      _.forEach(blockTypeSpecificRules, function (rule, i) {
        var answer = _.find(answers, { blockId: rule.parentBlockId });
        if (angular.isDefined(answer) && answer.value !== '') {
          var answerValue;
          var ruleValue;
          if (angular.isObject(answer.value)) {//answer of checkboxquestion will be an object
            answerValue = angular.isDefined(answer.value[rule.value]) ? answer.value[rule.value] : false;
            ruleValue = true;
          } else {
            //If string is a number, parse it as a float for numerical comparison
            answerValue = !isNaN(answer.value) ? parseFloat(answer.value) : answer.value;
            ruleValue = !isNaN(rule.value) ? parseFloat(rule.value) : rule.value;
          }

          if (rule.operator === '=' && answerValue === ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '!=' && answerValue !== ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '>' && answerValue > ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '<' && answerValue < ruleValue) {
            validRuleCount++;
          }
        }
        if ((ruleOperand === 'OR' && validRuleCount > 0) || (ruleOperand === 'AND' && validRuleCount <= i)) {
          return false; // Exit lodash foreach as we found a case which determines the whole outcome of this function
        }
      });

      return !blockTypeSpecificRules || blockTypeSpecificRules.length === 0 || // If no rules are set
        (ruleOperand === 'OR' && validRuleCount > 0) ||
        (ruleOperand === 'AND' && validRuleCount === blockTypeSpecificRules.length);
    };

    var choiceVisibleRuleCheck = function(block, choice, registrant, ruleType){
      var answers = registrant.answers;
      var ruleOperand = '';
      var validRuleCount = 0;
      var blockTypeSpecificRules = [];

      if (ruleType === ruleTypeConstants.SHOW_OPTION) {
        blockTypeSpecificRules = _.filter(block.rules, { 'ruleType': ruleType, 'blockEntityOption': choice.value });
        ruleOperand = 'OR';
      } else {
        if($window.Rollbar){
          $window.Rollbar.error('choiceVisibleRuleCheck was called with an unknown rule type: ', ruleType);
        }
        ruleOperand = 'AND';
      }

      if($window.Rollbar && !_.isArray(blockTypeSpecificRules)) {
        $window.Rollbar.info('Block rules value in blockVisibleRuleCheck, ruleType: ' + ruleType + ', typeof: ' + typeof(blockTypeSpecificRules) + ', JSON.stringify: ' + JSON.stringify(blockTypeSpecificRules));
      }

      _.forEach(blockTypeSpecificRules, function (rule, i) {
        var answer = _.find(answers, { blockId: rule.parentBlockId });
        if (angular.isDefined(answer) && answer.value !== '') {
          var answerValue;
          var ruleValue;
          if (angular.isObject(answer.value)) {//answer of checkboxquestion will be an object
            answerValue = angular.isDefined(answer.value[rule.value]) ? answer.value[rule.value] : false;
            ruleValue = true;
          } else {
            //If string is a number, parse it as a float for numerical comparison
            answerValue = !isNaN(answer.value) ? parseFloat(answer.value) : answer.value;
            ruleValue = !isNaN(rule.value) ? parseFloat(rule.value) : rule.value;
          }

          if (rule.operator === '=' && answerValue === ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '!=' && answerValue !== ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '>' && answerValue > ruleValue) {
            validRuleCount++;
          } else if (rule.operator === '<' && answerValue < ruleValue) {
            validRuleCount++;
          }
        }
        if ((ruleOperand === 'OR' && validRuleCount > 0) || (ruleOperand === 'AND' && validRuleCount <= i)) {
          return false; // Exit lodash foreach as we found a case which determines the whole outcome of this function
        }
      });

      return !blockTypeSpecificRules || blockTypeSpecificRules.length === 0 || // If no rules are set
        (ruleOperand === 'OR' && validRuleCount > 0) ||
        (ruleOperand === 'AND' && validRuleCount === blockTypeSpecificRules.length);
    };

    var blockInRegistrantType = function(block, registrant){
      return !_.includes(block.registrantTypes, registrant.registrantTypeId);
    };

    this.blockVisible = function(block, registrant, isAdmin){
      var visible = angular.isDefined(registrant) && blockVisibleRuleCheck(block, registrant, ruleTypeConstants.SHOW_QUESTION) && blockInRegistrantType(block, registrant);
      return (block.adminOnly && !isAdmin) ? false : visible;
    };

    this.choiceVisible = function(block, choice, registrant){
      return angular.isDefined(registrant) && choiceVisibleRuleCheck(block, choice, registrant, ruleTypeConstants.SHOW_OPTION) && blockInRegistrantType(block, registrant);
    };

    this.checkboxDisable = function(block, registrant){
      return blockVisibleRuleCheck(block, registrant, ruleTypeConstants.FORCE_SELECTION);
    };

    this.validate = function(conference, registrant, page) {
      var invalidBlocks = [];
      conference = angular.copy(conference);
      var blocks = page ? _.find(conference.registrationPages, {id: page}).blocks : _.flatten(_.map(conference.registrationPages, 'blocks'));

      angular.forEach(blocks, function(block){
        if (!block.required || block.adminOnly || !blockVisibleRuleCheck(block, registrant, ruleTypeConstants.SHOW_QUESTION) || !blockInRegistrantType(block, registrant)) { return; }

        var answer = _.find(registrant.answers, { 'blockId': block.id });
        if (angular.isUndefined(answer)) {
          invalidBlocks.push(block.id);
          return;
        }
        answer = answer.value;

        switch (block.type) {
          case 'nameQuestion':
            if (_.isEmpty(answer.firstName) || _.isEmpty(answer.lastName)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'emailQuestion':
            if (_.isEmpty(answer) || _.isNull(answer.match(/^.+@.+$/))) { //Contains an @ sign surrounded by at least one character
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'numberQuestion':
            if (!_.isNumber(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'phoneQuestion':
            if (_.isNull(answer) || _.isNull(answer.match(/^(\D*\d\D*){10,15}$/))) { //Contains 10-15 digits
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'checkboxQuestion':
            if (_.isEmpty(answer) || _.isEmpty(_.pickBy(answer))) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'addressQuestion':
            if (_.isEmpty(answer.address1) || _.isEmpty(answer.state)  || _.isEmpty(answer.city)  || _.isEmpty(answer.zip)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          default:
            if(_.isEmpty(answer)){
              invalidBlocks.push(block.id);
              return;
            }
            break;
        }
      });

      return invalidBlocks;
    };
  });
<|endoftext|>


<commit_before>'use strict';

angular.module('ui.dashboard.widgets')
  .directive('wtLineChart', function () {
    return {
      template: '

',
      scope: {
        chart: '='
      },
      replace: true,
      link: function postLink(scope, element) {
        var lineChart = new google.visualization.LineChart(element[0]);

        function draw(chart) {
          var data = chart.data;

          var table = new google.visualization.DataTable();
          table.addColumn('datetime');
          table.addColumn('number');
          table.addRows(data.length);

          var view = new google.visualization.DataView(table);

          for (var i = 0; i < data.length; i++) {
            var item = data[i];
            table.setCell(i, 0, new Date(item.timestamp));
            var value = parseFloat(item.value);
            table.setCell(i, 1, value);
          }

          var chartOptions = {
            legend: 'none',
            vAxis: { minValue: 0, maxValue: 100 }
            //chartArea: { top: 20, left: 30, height: 240 }
          };

          if (chart.max) {
            var lastTimestamp;

            if (data.length) {
              var last = data[data.length - 1];
              lastTimestamp = last.timestamp;
            } else {
              lastTimestamp = Date.now();
            }

            var max = new Date(lastTimestamp);
            var min = new Date(lastTimestamp - (chart.max - 1) * 1000);

            angular.extend(chartOptions, {
              hAxis: { viewWindow: { min: min, max: max }}
            });
          }

          lineChart.draw(view, chartOptions);
        }

        scope.$watch('chart', function (chart) {
          if (!chart) {
            chart = {
              data: [],
              max: 30
            };
          }

          if (chart.data) {
            draw(chart);
          }
        });
      }
    };
  });<commit_msg>Line Chart Options<commit_after>'use strict';

angular.module('ui.dashboard.widgets')
  .directive('wtLineChart', function () {
    return {
      template: '

',
      scope: {
        chart: '='
      },
      replace: true,
      link: function postLink(scope, element) {
        var lineChart = new google.visualization.LineChart(element[0]);

        function draw(chart) {
          var data = chart.data;

          var table = new google.visualization.DataTable();
          table.addColumn('datetime');
          table.addColumn('number');
          table.addRows(data.length);

          var view = new google.visualization.DataView(table);

          for (var i = 0; i < data.length; i++) {
            var item = data[i];
            table.setCell(i, 0, new Date(item.timestamp));
            var value = parseFloat(item.value);
            table.setCell(i, 1, value);
          }

          var chartOptions = {
            legend: 'none',
            vAxis: { minValue: 0, maxValue: 100 }
            //chartArea: { top: 20, left: 30, height: 240 }
          };

          if (chart.max) {
            var lastTimestamp;

            if (data.length) {
              var last = data[data.length - 1];
              lastTimestamp = last.timestamp;
            } else {
              lastTimestamp = Date.now();
            }

            var max = new Date(lastTimestamp);
            var min = new Date(lastTimestamp - (chart.max - 1) * 1000);

            angular.extend(chartOptions, {
              hAxis: { viewWindow: { min: min, max: max }}
            });
          }

          if (chart.chartOptions) {
            angular.extend(chartOptions, chart.chartOptions);
          }

          lineChart.draw(view, chartOptions);
        }

        scope.$watch('chart', function (chart) {
          if (!chart) {
            chart = {
              data: [],
              max: 30
            };
          }

          if (chart.data) {
            draw(chart);
          }
        });
      }
    };
  });<|endoftext|>


<commit_before>"use strict"

const   mongoose = require('mongoose'),
    Article = require('../../models/Article');

module.exports = (callback, res) => {

  let data = {}

  Article.find()
    .sort({'date': -1})
    .limit(20)
    .exec((err, articles)=>{
      if (err) console.log(err)

      if (!articles) {
        res.status(204).send({data: null})
      } else {
        callback(articles);
      } //end else
  }) // end find

}

<commit_msg>change recent article query to ignore articles that don't have concept maps available<commit_after>"use strict"

const   mongoose = require('mongoose'),
    Article = require('../../models/Article');

module.exports = (callback, res) => {

  let data = {}

  Article.find()
    .where({ 'concepts': { $ne: [] } })
    .sort({'date': -1})
    .limit(20)
    .exec((err, articles)=>{
      if (err) console.log(err)

      if (!articles) {
        res.status(204).send({data: null})
      } else {
        callback(articles);
      } //end else
  }) // end find

}

<|endoftext|>