<commit_before>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/lib/domplate",
    "firebug/lib/dom",
    "firebug/lib/css",
    "firebug/lib/array",
    "firebug/lib/string",
    "firebug/lib/trace",
    "firebug/chrome/domTree",
    "firebug/dom/toggleBranch",
],
function(Obj, Domplate, Dom, Css, Arr, Str, FBTrace, DomTree, ToggleBranch) {
with (Domplate) {

// ********************************************************************************************* //
// Constants

var Trace = FBTrace.to("DBG_DOMBASETREE");
var TraceError = FBTrace.to("DBG_ERRORS");

// ********************************************************************************************* //
// DOM Tree Implementation

function DomBaseTree()
{
}

/**
 * @domplate
 */
var BaseTree = DomTree.prototype;
DomBaseTree.prototype = domplate(BaseTree,
/** @lends DomBaseTree */
{
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Persistence

    saveState: function(state)
    {
        if (!this.element)
            return;

        var rows = this.element.querySelectorAll(".memberRow.opened");
        for (var i=0; i<rows.length; i++)
        {
            var row = rows[i];
            var path = this.getPath(row);

FBTrace.sysout("saveState path: " + path.join("/"), path)

            // Mark the path in the toggle tree
            var toggles = state;
            for (var j=0; j<path.length; ++j)
            {
                var name = path[j];
                if (toggles.get(name))
                    toggles = toggles.get(name);
                else
                    toggles = toggles.set(name, new ToggleBranch.ToggleBranch());
            }
        }

FBTrace.sysout("saveState toggles: ", state)
    },

    restoreState: function(object, toggles, level)
    {
        // Don't try to expand children if there are no expanded items.
        if (toggles.isEmpty())
            return;

        var members = this.getMembers(object, level);
        FBTrace.sysout("RestoreState; members: ", members);
        for (var i=0; i<members.length; i++)
        {
            var member = members[i];

            // Don't expand if the member doesn't have children any more.
            if (!member.hasChildren)
                continue;

            var name = this.provider.getId(member.value);

            var newToggles = toggles.get(name);
            if (!newToggles)
                continue;

            toggles.remove(name);

            FBTrace.sysout("RestoreState; expand id: " + name, member);

            // Get the member's object (the value) and expand it.
            var value = member.value;
            var promise = this.expandObject(value);

            // If no children are expanded bail out.
            if (newToggles.isEmpty())
                continue;

            if (promise)
            {
                var self = this;
                promise.then(function()
                {
                    self.restoreState(value, newToggles, level+1);
                })
            }
            else
            {
                this.restoreState(value, newToggles, level+1);
            }
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    toggleRow: function(row, forceOpen)
    {
        if (!row)
            return;

        var member = row.repObject;
        if (!member)
            return;

        var level = parseInt(row.getAttribute("level"));
        if (forceOpen && Css.hasClass(row, "opened"))
            return;

        // Handle long strings. These don't have children, but can be shortened and
        // expanding them allows the user to see the entire string.
        var rowValue = this.getValue(member);
        var isString = typeof(rowValue) == "string";
        if (isString)
        {
            if (Css.hasClass(row, "opened"))
            {
                Css.removeClass(row, "opened");
                row.lastChild.firstChild.textContent = '"' + Str.cropMultipleLines(rowValue) + '"';
            }
            else
            {
                Css.setClass(row, "opened");
                row.lastChild.firstChild.textContent = '"' + rowValue + '"';
            }

            return;
        }

try {
	        BaseTree.toggleRow.apply(this, arguments);

} catch (e) {
FBTrace.sysout("EXCEPTION " + e, e);
}

    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    getPath: function(row)
    {
        var name = this.getRowName(row);
        var path = [name];

        var level = parseInt(row.getAttribute("level"), 10) - 1;
        for (row = row.previousSibling; row && level >= 0; row = row.previousSibling)
        {
            if (parseInt(row.getAttribute("level"), 10) === level)
            {
                name = this.getRowName(row);
                path.splice(0, 0, name);

                --level;
            }
        }

        return path;
    },

    getRowName: function(row)
    {
try {
	        var member = row.repObject;
        return this.provider.getId(member.value);

} catch (e) {
FBTrace.sysout("EXCEPTION "  + e, e)
}

    }
});

// ********************************************************************************************* //
// Registration

return DomBaseTree;

// ********************************************************************************************* //
}});

<commit_msg>Remove debug tracing<commit_after>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/lib/domplate",
    "firebug/lib/dom",
    "firebug/lib/css",
    "firebug/lib/array",
    "firebug/lib/string",
    "firebug/lib/trace",
    "firebug/chrome/domTree",
    "firebug/dom/toggleBranch",
],
function(Obj, Domplate, Dom, Css, Arr, Str, FBTrace, DomTree, ToggleBranch) {
with (Domplate) {

// ********************************************************************************************* //
// Constants

var Trace = FBTrace.to("DBG_DOMBASETREE");
var TraceError = FBTrace.to("DBG_ERRORS");

// ********************************************************************************************* //
// DOM Tree Implementation

function DomBaseTree()
{
}

/**
 * @domplate
 */
var BaseTree = DomTree.prototype;
DomBaseTree.prototype = domplate(BaseTree,
/** @lends DomBaseTree */
{
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Persistence

    saveState: function(state)
    {
        if (!this.element)
            return;

        var rows = this.element.querySelectorAll(".memberRow.opened");
        for (var i=0; i<rows.length; i++)
        {
            var row = rows[i];
            var path = this.getPath(row);

            // Mark the path in the toggle tree
            var toggles = state;
            for (var j=0; j<path.length; ++j)
            {
                var name = path[j];
                if (toggles.get(name))
                    toggles = toggles.get(name);
                else
                    toggles = toggles.set(name, new ToggleBranch.ToggleBranch());
            }
        }
    },

    restoreState: function(object, toggles, level)
    {
        // Don't try to expand children if there are no expanded items.
        if (toggles.isEmpty())
            return;

        var members = this.getMembers(object, level);
        for (var i=0; i<members.length; i++)
        {
            var member = members[i];

            // Don't expand if the member doesn't have children any more.
            if (!member.hasChildren)
                continue;

            var name = this.provider.getId(member.value);

            var newToggles = toggles.get(name);
            if (!newToggles)
                continue;

            toggles.remove(name);

            // Get the member's object (the value) and expand it.
            var value = member.value;
            var promise = this.expandObject(value);

            // If no children are expanded bail out.
            if (newToggles.isEmpty())
                continue;

            if (promise)
            {
                var self = this;
                promise.then(function()
                {
                    self.restoreState(value, newToggles, level+1);
                })
            }
            else
            {
                this.restoreState(value, newToggles, level+1);
            }
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    toggleRow: function(row, forceOpen)
    {
        if (!row)
            return;

        var member = row.repObject;
        if (!member)
            return;

        var level = parseInt(row.getAttribute("level"));
        if (forceOpen && Css.hasClass(row, "opened"))
            return;

        // Handle long strings. These don't have children, but can be shortened and
        // expanding them allows the user to see the entire string.
        var rowValue = this.getValue(member);
        var isString = typeof(rowValue) == "string";
        if (isString)
        {
            if (Css.hasClass(row, "opened"))
            {
                Css.removeClass(row, "opened");
                row.lastChild.firstChild.textContent = '"' + Str.cropMultipleLines(rowValue) + '"';
            }
            else
            {
                Css.setClass(row, "opened");
                row.lastChild.firstChild.textContent = '"' + rowValue + '"';
            }

            return;
        }

        BaseTree.toggleRow.apply(this, arguments);
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    getPath: function(row)
    {
        var name = this.getRowName(row);
        var path = [name];

        var level = parseInt(row.getAttribute("level"), 10) - 1;
        for (row = row.previousSibling; row && level >= 0; row = row.previousSibling)
        {
            if (parseInt(row.getAttribute("level"), 10) === level)
            {
                name = this.getRowName(row);
                path.splice(0, 0, name);

                --level;
            }
        }

        return path;
    },

    getRowName: function(row)
    {
        var member = row.repObject;
        return this.provider.getId(member.value);
    }
});

// ********************************************************************************************* //
// Registration

return DomBaseTree;

// ********************************************************************************************* //
}});

<|endoftext|>


<commit_before>import { Component } from 'react';
import { Form, FormControl , FormGroup, Col, Button, ControlLabel, Checkbox, Image, ListGroup, ListGroupItem } from 'react-bootstrap';
import request from 'superagent';

const APP_URI = 'http://localhost:3000';

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

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

  componentDidMount() {
    request
      .get(`${APP_URI}/api/gallery`)
      .then(galleries => {
        let galleryList = [];
        galleries.body.map(item => galleryList.push(item));
        this.setState({ galleryList });
      });
  }

  render() {
    console.log('this.state.galleryList.length', this.state.galleryList.length);
    return (

        <ListGroup>
          {
            this.state.galleryList.map((gallery, index) => {
              return <ListGroupItem key={index}>{gallery.name}</ListGroupItem>
            })
         }
        </ListGroup>

    );
  }
}

export default ListGallery;
<commit_msg>working on gallery<commit_after>import { Component } from 'react';
import { Form, FormControl , FormGroup, Col, Button, ControlLabel, Checkbox, Image, ListGroup, ListGroupItem } from 'react-bootstrap';
import request from 'superagent';

const APP_URI = 'http://localhost:3000';

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

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

  componentDidMount() {
    request
      .get(`${APP_URI}/api/gallery`)
      .then(galleries => {
        let galleryList = [];
        galleries.body.map(item => galleryList.push(item));
        this.setState({ galleryList });
      });
  }

  /* shouldComponentUpdate: is always called before the render
  method and enables to define if a re-rendering is needed or can be skipped*/
  shouldComponentUpdate(nextProps, nextState) {
    // return a boolean value
    return true;
  }

  /*componentWillUpdate gets called as soon as the the shouldComponentUpdate
  returned true. Any state changes via this.setState are not allowed as this
  method should be strictly used to prepare for an upcoming update not trigger
  an update itself.*/
  componentWillUpdate(nextProps, nextState){
    // perform any preparations for an upcoming update
  }
  /*Finally componentDidUpdate is called after the render method. Similar
  to the componentDidMount, this method can be used to perform DOM operations
  after the data has been updated.*/
  componentDidUpdate(prevProps, prevState){
    //
  }
  render() {
    return (

        <ListGroup>
          { this.state.galleryList.map((gallery, index) => {
            return <ListGroupItem key={index}>{gallery.name}</ListGroupItem>;
          })
         }
        </ListGroup>

    );
  }
}

export default ListGallery;
<|endoftext|>


<commit_before>/**
 * Author: Tony Brix, https://Tony.Brix.ninja
 * Repo: https://github.com/UziTech/jquery.el.js
 * License: MIT
 * Version: 0.1.0
 *
 * simple way to create elements in jquery
 * example:
 * $.el("table#tab1[border=0]").el("tbody").el("tr.odd").el("td{text}");
 */

(function ($) {
	function isStartTokenChar(char) {
		return /[#\.\[\{]/.test(char);
	}

	function startNextToken(char) {
		switch (char) {
			case null:
				return;
			case "#":
				return {
					type: "id",
					value: ""
				};
			case ".":
				return {
					type: "class",
					value: ""
				};
			case "[":
				return {
					type: "attrs",
					value: ""
				};
			case "{":
				return {
					type: "text",
					value: ""
				};
			default:
				throw "'" + char + "' is not a valid start of a token";
		}
	}

	function parseAttrs(attrs, text) {
		text = text.trim();
		var token = "next";
		var inString = false;
		var inWhitespace = false;
		var attr = {
			name: "",
			value: ""
		};
		for (var i = 0; i <= text.length; i++) {
			var char = null;
			if (i < text.length) {
				char = text[i];
				switch (token) {
					case "name":
						if (char === "=") {
							token = "equals";
							inWhitespace = false;
						} else if (/\s/.test(char)) {
							inWhitespace = true;
						} else if (inWhitespace) {
							// empty attr
							attrs[attr.name] = "";
							attr = {
								name: "",
								value: ""
							};
							inWhitespace = false;
							token = "name";
							if (/[\w-]/.test(char)) {
								attr.name += char;
							} else {
								throw "'" + char + "' is not a valid attribute name character";
							}
						} else if (/[\w-]/.test(char)) {
							attr.name += char;
						} else {
							throw "'" + char + "' is not a valid attribute name character";
						}
						break;
					case "equals":
						if (/\s/.test(char)) {
							// ignore whitespace
						} else if (/["']/.test(char)) {
							inString = char;
							token = "value";
						} else {
							attr.value += char;
							token = "value";
						}
						break;
					case "value":
						if (inString) {
							if (char === "\\") {
								if (text.length > i + 1) {
									var nextInStringChar = text[i + 1];
									switch (nextInStringChar) {
										case "\\":
										case "'":
										case "\"":
											attr.value += nextInStringChar;
											i++;
											break;
										default:
											attr.value += char;
									}
								} else {
									attr.value += char;
								}
							} else if (char === inString) {
								inString = false;
								attrs[attr.name] = attr.value;
								attr = {
									name: "",
									value: ""
								};
								token = "next";
							} else {
								attr.value += char;
							}
						} else {
							if (char === "\\") {
								if (text.length > i + 1) {
									var nextChar = text[i + 1];
									switch (nextChar) {
										case "\\":
											attr.value += nextChar;
											i++;
											break;
										default:
											attr.value += char;
									}
								} else {
									attr.value += char;
								}
							} else if (/\s/.test(char)) {
								attrs[attr.name] = attr.value;
								attr = {
									name: "",
									value: ""
								};
								token = "next";
							} else {
								attr.value += char;
							}
						}
						break;
					case "next":
						if (/[\w-]/.test(char)) {
							inWhitespace = false;
							attr.name += char;
							token = "name";
						} else if (/[^\s]/.test(char)) {
							throw "'" + char + "' is not a valid attribute name character";
						}
						break;
					default:
						// this should never happen
						throw "'" + token + "' is an invalid token";
				}
			} else {
				if (attr.name) {
					attrs[attr.name] = attr.value;
				}
			}
		}
		return attrs;
	}

	function parseText(text) {
		if (typeof text === "undefined") {
			text = "";
		}
		if (typeof text !== "string") {
			throw "invalid input";
		}
		text = text.trim();
		var el = {
			tag: "div",
			id: null,
			classes: [],
			attrs: {},
			text: ""
		};
		var token = {
			type: "tag",
			value: "",
		};
		for (var i = 0; i <= text.length; i++) {

			var char = null;
			if (i < text.length) {
				char = text[i];
			}
			switch (token.type) {
				case "tag":
					if (char && /\w/.test(char)) {
						token.value += char;
					} else {
						if (token.value) {
							el.tag = token.value;
						}
						token = startNextToken(char);
					}
					break;
				case "id":
					if (char === "\\") {
						if (text.length > i + 1) {
							var nextIdChar = text[i + 1];
							if (nextIdChar === "\\" || isStartTokenChar(nextIdChar)) {
								token.value += nextIdChar;
								i++;
							} else {
								token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (char && !isStartTokenChar(char)) {
						token.value += char;
					} else {
						if (!token.value) {
							if (char === null) {
								throw "id cannot be empty";
							} else {
								throw "'" + char + "' is not a valid id character";
							}
						}
						if (el.id) {
							throw "cannot have multiple ids";
						} else {
							el.id = token.value;
							token = startNextToken(char);
						}
					}
					break;
				case "class":
					if (char === "\\") {
						if (text.length > i + 1) {
							var nextClassChar = text[i + 1];
							if (nextClassChar === "\\" || isStartTokenChar(nextClassChar)) {
								token.value += nextClassChar;
								i++;
							} else {
								token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (char && !isStartTokenChar(char)) {
						token.value += char;
					} else {
						if (!token.value) {
							if (char === null) {
								throw "class cannot be empty";
							} else {
								throw "'" + char + "' is not a valid class character";
							}
						}
						el.classes.push(token.value);
						token = startNextToken(char);
					}
					break;
				case "attrs":
					if (char === null) {
						throw "missing ']' at end of attributes token";
					} else if (char === "\\") {
						if (text.length > i + 1) {
							var nextAttrChar = text[i + 1];
							switch (nextAttrChar) {
								case "\\":
									token.value += "\\\\";
									i++;
									break;
								case "]":
									token.value += nextAttrChar;
									i++;
									break;
								default:
									token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (/[^\]]/.test(char)) {
						token.value += char;
					} else {
						parseAttrs(el.attrs, token.value);
						token = {
							type: "next"
						};
					}
					break;
				case "text":
					if (char === null) {
						throw "missing '}' at end of text token";
					} else if (char === "\\") {
						if (text.length > i + 1) {
							var nextTextChar = text[i + 1];
							switch (nextTextChar) {
								case "\\":
								case "}":
									token.value += nextTextChar;
									i++;
									break;
								default:
									token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (/[^}]/.test(char)) {
						token.value += char;
					} else {
						el.text += token.value;
						token = {
							type: "next"
						};
					}
					break;
				case "next":
					if (char) {
						token = startNextToken(char);
					}
					break;
				default:
					// this should never happen
					throw "'" + token.type + "' is not a valid token type";
			}
		}
		return el;
	}

	$.el = function (text) {
		var el = parseText(text);
		var $el = $("<" + el.tag + " />");
		if (el.id) {
			$el.attr({ id: el.id });
		}
		if (el.classes.length > 0) {
			$el.addClass(el.classes.join(" "));
		}
		if (el.attrs) {
			$el.attr(el.attrs);
		}
		if (el.text) {
			$el.text(el.text);
		}
		return $el;
	};

	$.fn.el = function (text, returnParent) {
		var $el = $.el(text).appendTo(this);
		if (returnParent) {
			return this;
		}
		return $el;
	};
})(jQuery);
<commit_msg>allow tag to be any character<commit_after>/**
 * Author: Tony Brix, https://Tony.Brix.ninja
 * Repo: https://github.com/UziTech/jquery.el.js
 * License: MIT
 * Version: 0.1.0
 *
 * simple way to create elements in jquery
 * example:
 * $.el("table#tab1[border=0]").el("tbody").el("tr.odd").el("td{text}");
 */

(function ($) {
	function isStartTokenChar(char) {
		return /[#\.\[\{]/.test(char);
	}

	function startNextToken(char) {
		switch (char) {
			case null:
				return;
			case "#":
				return {
					type: "id",
					value: ""
				};
			case ".":
				return {
					type: "class",
					value: ""
				};
			case "[":
				return {
					type: "attrs",
					value: ""
				};
			case "{":
				return {
					type: "text",
					value: ""
				};
			default:
				throw "'" + char + "' is not a valid start of a token";
		}
	}

	function parseAttrs(attrs, text) {
		text = text.trim();
		var token = "next";
		var inString = false;
		var inWhitespace = false;
		var attr = {
			name: "",
			value: ""
		};
		for (var i = 0; i <= text.length; i++) {
			var char = null;
			if (i < text.length) {
				char = text[i];
				switch (token) {
					case "name":
						if (char === "=") {
							token = "equals";
							inWhitespace = false;
						} else if (/\s/.test(char)) {
							inWhitespace = true;
						} else if (inWhitespace) {
							// empty attr
							attrs[attr.name] = "";
							attr = {
								name: "",
								value: ""
							};
							inWhitespace = false;
							token = "name";
							if (/[\w-]/.test(char)) {
								attr.name += char;
							} else {
								throw "'" + char + "' is not a valid attribute name character";
							}
						} else if (/[\w-]/.test(char)) {
							attr.name += char;
						} else {
							throw "'" + char + "' is not a valid attribute name character";
						}
						break;
					case "equals":
						if (/\s/.test(char)) {
							// ignore whitespace
						} else if (/["']/.test(char)) {
							inString = char;
							token = "value";
						} else {
							attr.value += char;
							token = "value";
						}
						break;
					case "value":
						if (inString) {
							if (char === "\\") {
								if (text.length > i + 1) {
									var nextInStringChar = text[i + 1];
									switch (nextInStringChar) {
										case "\\":
										case "'":
										case "\"":
											attr.value += nextInStringChar;
											i++;
											break;
										default:
											attr.value += char;
									}
								} else {
									attr.value += char;
								}
							} else if (char === inString) {
								inString = false;
								attrs[attr.name] = attr.value;
								attr = {
									name: "",
									value: ""
								};
								token = "next";
							} else {
								attr.value += char;
							}
						} else {
							if (char === "\\") {
								if (text.length > i + 1) {
									var nextChar = text[i + 1];
									switch (nextChar) {
										case "\\":
											attr.value += nextChar;
											i++;
											break;
										default:
											attr.value += char;
									}
								} else {
									attr.value += char;
								}
							} else if (/\s/.test(char)) {
								attrs[attr.name] = attr.value;
								attr = {
									name: "",
									value: ""
								};
								token = "next";
							} else {
								attr.value += char;
							}
						}
						break;
					case "next":
						if (/[\w-]/.test(char)) {
							inWhitespace = false;
							attr.name += char;
							token = "name";
						} else if (/[^\s]/.test(char)) {
							throw "'" + char + "' is not a valid attribute name character";
						}
						break;
					default:
						// this should never happen
						throw "'" + token + "' is an invalid token";
				}
			} else {
				if (attr.name) {
					attrs[attr.name] = attr.value;
				}
			}
		}
		return attrs;
	}

	function parseText(text) {
		if (typeof text === "undefined") {
			text = "";
		}
		if (typeof text !== "string") {
			throw "invalid input";
		}
		text = text.trim();
		var el = {
			tag: "div",
			id: null,
			classes: [],
			attrs: {},
			text: ""
		};
		var token = {
			type: "tag",
			value: "",
		};
		for (var i = 0; i <= text.length; i++) {

			var char = null;
			if (i < text.length) {
				char = text[i];
			}
			switch (token.type) {
				case "tag":
					if (char === "\\") {
						if (text.length > i + 1) {
							var nextTagChar = text[i + 1];
							if (nextTagChar === "\\" || isStartTokenChar(nextTagChar)) {
								token.value += nextTagChar;
								i++;
							} else {
								token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (char && !isStartTokenChar(char)) {
						token.value += char;
					} else {
						if (token.value) {
							el.tag = token.value;
						}
						token = startNextToken(char);
					}
					break;
				case "id":
					if (char === "\\") {
						if (text.length > i + 1) {
							var nextIdChar = text[i + 1];
							if (nextIdChar === "\\" || isStartTokenChar(nextIdChar)) {
								token.value += nextIdChar;
								i++;
							} else {
								token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (char && !isStartTokenChar(char)) {
						token.value += char;
					} else {
						if (!token.value) {
							if (char === null) {
								throw "id cannot be empty";
							} else {
								throw "'" + char + "' is not a valid id character";
							}
						}
						if (el.id) {
							throw "cannot have multiple ids";
						} else {
							el.id = token.value;
							token = startNextToken(char);
						}
					}
					break;
				case "class":
					if (char === "\\") {
						if (text.length > i + 1) {
							var nextClassChar = text[i + 1];
							if (nextClassChar === "\\" || isStartTokenChar(nextClassChar)) {
								token.value += nextClassChar;
								i++;
							} else {
								token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (char && !isStartTokenChar(char)) {
						token.value += char;
					} else {
						if (!token.value) {
							if (char === null) {
								throw "class cannot be empty";
							} else {
								throw "'" + char + "' is not a valid class character";
							}
						}
						el.classes.push(token.value);
						token = startNextToken(char);
					}
					break;
				case "attrs":
					if (char === null) {
						throw "missing ']' at end of attributes token";
					} else if (char === "\\") {
						if (text.length > i + 1) {
							var nextAttrChar = text[i + 1];
							switch (nextAttrChar) {
								case "\\":
									token.value += "\\\\";
									i++;
									break;
								case "]":
									token.value += nextAttrChar;
									i++;
									break;
								default:
									token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (/[^\]]/.test(char)) {
						token.value += char;
					} else {
						parseAttrs(el.attrs, token.value);
						token = {
							type: "next"
						};
					}
					break;
				case "text":
					if (char === null) {
						throw "missing '}' at end of text token";
					} else if (char === "\\") {
						if (text.length > i + 1) {
							var nextTextChar = text[i + 1];
							switch (nextTextChar) {
								case "\\":
								case "}":
									token.value += nextTextChar;
									i++;
									break;
								default:
									token.value += char;
							}
						} else {
							token.value += char;
						}
					} else if (/[^}]/.test(char)) {
						token.value += char;
					} else {
						el.text += token.value;
						token = {
							type: "next"
						};
					}
					break;
				case "next":
					if (char) {
						token = startNextToken(char);
					}
					break;
				default:
					// this should never happen
					throw "'" + token.type + "' is not a valid token type";
			}
		}
		return el;
	}

	$.el = function (text) {
		var el = parseText(text);
		var $el = $("<" + el.tag + " />");
		if (el.id) {
			$el.attr({ id: el.id });
		}
		if (el.classes.length > 0) {
			$el.addClass(el.classes.join(" "));
		}
		if (el.attrs) {
			$el.attr(el.attrs);
		}
		if (el.text) {
			$el.text(el.text);
		}
		return $el;
	};

	$.fn.el = function (text, returnParent) {
		var $el = $.el(text).appendTo(this);
		if (returnParent) {
			return this;
		}
		return $el;
	};
})(jQuery);
<|endoftext|>


<commit_before>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
define([
    'jquery'
], function($) {
    'use strict';
    var storage = {};

    function setClass(element, value) {
        $(element).each(function() {
            $(this).addClass(value);
        });
    }

    function setAttr(element, attribute, value) {
        $(element).each(function() {
            $(this).attr(attribute, value);
        });
    }

    function toJson(objects) {
        var json = {};
        if (arguments.length) {
            json = JSON.stringify(objects);
        }
        return json;
    }

    storage.Session = function(name) {
        var that = this;
        if (arguments.length) {
            that.name = name;
            that.objects = null;
        }
    };

    storage.load = function(name) {
        var loaded = false,
            sessionItem,
            sessionState = {},
            key,
            data;
        if (window.Storage) {
            if (arguments.length) {
                sessionItem = sessionStorage.getItem(name);
                if (sessionItem) {
                    sessionState = JSON.parse(sessionItem);
                    for (key in sessionState) {
                        if (sessionState.hasOwnProperty(key)) {
                            data = sessionState[key];
                            if (data.value !== null && data.value !== '') {
                                switch (data.type) {
                                    case 'attr':
                                        loaded = loaded || true;
                                        setAttr(key, data.name, data.value);
                                        break;
                                    case 'class':
                                        loaded = loaded || true;
                                        setClass(key, data.value);
                                        break;
                                    default:
                                        loaded = loaded && false;
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        } else {
            console.warn('Loading from session/local storage is not supported');
        }
        return loaded;
    };

    storage.save = function(session) {
        if (window.Storage) {
            try {
                sessionStorage.setItem(session.name, toJson(session.objects));
            } catch (e) {
                if (e === QUOTA_EXCEEDED_ERR) {
                    console.error(
                        'Error saving to session storage: quota exceeded');
                } else {
                    console.error('Error saving to session storage');
                }
            }
        } else {
            console.warn('Saving to session/local storage is not supported');
        }
    };

    return storage;
});
<commit_msg>Rework web storage logic.<commit_after>/*! Kernel CI Dashboard | Licensed under the GNU GPL v3 (or later) */
define(function() {
    'use strict';
    var storage = {};

    function setClass(selector, value) {
        [].forEach.call(
            document.querySelectorAll(selector),
            function(element) {
                element.className = value;
            }
        );
    }

    function setAttr(selector, attribute, value) {
        [].forEach.call(
            document.querySelectorAll(selector),
            function(element) {
                element.setAttribute(attribute, value);
            }
        );
    }

    function toJson(objects) {
        var json;

        json = {};
        if (objects !== null && objects !== undefined) {
            json = JSON.stringify(objects);
        }

        return json;
    }

    function loadSessionData(key, data) {
        var loaded;
        loaded = false;

        if (data.value !== null && data.value !== '') {
            switch (data.type) {
                case 'attr':
                    loaded = loaded || true;
                    setAttr(key, data.name, data.value);
                    break;
                case 'class':
                    loaded = loaded || true;
                    setClass(key, data.value);
                    break;
                default:
                    loaded = false;
                    break;
            }
        }

        return loaded;
    }

    function parseSessionData(key, data) {
        var loaded,
            eachLoaded;

        loaded = false;
        if (data.constructor === Array) {
            data.forEach(function(value) {
                eachLoaded = loadSessionData(key, value);
                loaded = loaded || eachLoaded;
            });
        } else {
            loaded = loadSessionData(key, data);
        }

        return loaded;
    }

    storage.Session = function(name) {
        var that;

        that = this;
        if (name !== null && name !== undefined) {
            that.name = name;
            that.objects = null;
        }
    };

    storage.load = function(name) {
        var loaded,
            sessionItem,
            sessionState;

        loaded = false;
        if (window.Storage) {
            if (name !== null && name !== undefined) {
                sessionState = {};
                sessionItem = sessionStorage.getItem(name);
                if (sessionItem) {
                    sessionState = JSON.parse(sessionItem);
                    Object.keys(sessionState).forEach(function(key) {
                        loaded = parseSessionData(key, sessionState[key]);
                    });
                }
            }
        } else {
            console.warn('Loading from session storage is not supported');
        }
        return loaded;
    };

    storage.save = function(session) {
        if (window.Storage) {
            try {
                sessionStorage.setItem(session.name, toJson(session.objects));
            } catch (e) {
                if (e === QUOTA_EXCEEDED_ERR) {
                    console.error(
                        'Error saving to session storage: quota exceeded');
                } else {
                    console.error('Error saving to session storage');
                }
            }
        } else {
            console.warn('Saving to session/local storage is not supported');
        }
    };

    return storage;
});
<|endoftext|>


<commit_before>// @flow

import Spinner from '@atlaskit/spinner';

import React, { Component } from 'react';
import type { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';

import config from '../../config';
import { getSetting, setEmail, setName } from '../../settings';

import { conferenceEnded, conferenceJoined } from '../actions';
import JitsiMeetExternalAPI from '../external_api';
import { LoadingIndicator, Wrapper } from '../styled';

type Props = {

    /**
     * Redux dispatch.
     */
    dispatch: Dispatch<*>;

    /**
     * React Router location object.
     */
    location: Object;

    /**
     * AlwaysOnTop Window Enabled.
     */
    _alwaysOnTopWindowEnabled: boolean;

    /**
     * Email of user.
     */
    _email: string;

    /**
     * Name of user.
     */
    _name: string;

    /**
     * Default Jitsi Server URL.
     */
    _serverURL: string;

    /**
     * Default Jitsi Server Timeout.
     */
    _serverTimeout: number;

    /**
     * Start with Audio Muted.
     */
    _startWithAudioMuted: boolean;

    /**
     * Start with Video Muted.
     */
    _startWithVideoMuted: boolean;
};

type State = {

    /**
     * If the conference is loading or not.
     */
    isLoading: boolean;
};

/**
 * Conference component.
 */
class Conference extends Component<Props, State> {
    /**
     * External API object.
     */
    _api: Object;

    /**
     * Conference Object.
     */
    _conference: Object;

    /**
     * Timer to cancel the joining if it takes too long.
     */
    _loadTimer: ?TimeoutID;

    /**
     * Reference to the element of this component.
     */
    _ref: Object;

    /**
     * Initializes a new {@code Conference} instance.
     *
     * @inheritdoc
     */
    constructor() {
        super();

        this.state = {
            isLoading: true
        };

        this._ref = React.createRef();

        this._onIframeLoad = this._onIframeLoad.bind(this);
        this._onVideoConferenceEnded = this._onVideoConferenceEnded.bind(this);
    }

    /**
     * Attach the script to this component.
     *
     * @returns {void}
     */
    componentDidMount() {
        const room = this.props.location.state.room;
        const serverTimeout = this.props._serverTimeout || config.defaultServerTimeout;
        const serverURL = this.props.location.state.serverURL
            || this.props._serverURL
            || config.defaultServerURL;

        this._conference = {
            room,
            serverURL
        };

        this._loadConference();

        // Set a timer for a timeout duration, if we haven't loaded the iframe by then,
        // give up.
        this._loadTimer = setTimeout(() => {
            this._navigateToHome(

                // $FlowFixMe
                {
                    error: 'Loading error',
                    type: 'error'
                },
                room,
                serverURL);
        }, serverTimeout * 1000);
    }

    /**
     * Keep profile settings in sync with Conference.
     *
     * @param {Props} prevProps - Component's prop values before update.
     * @returns {void}
     */
    componentDidUpdate(prevProps) {
        const { props } = this;

        if (props._email !== prevProps._email) {
            this._setEmail(props._email);
        }
        if (props._name !== prevProps._name) {
            this._setName(props._name);
        }
    }

    /**
     * Remove conference on unmounting.
     *
     * @returns {void}
     */
    componentWillUnmount() {
        if (this._loadTimer) {
            clearTimeout(this._loadTimer);
        }
        if (this._api) {
            this._api.dispose();
        }
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @returns {ReactElement}
     */
    render() {
        return (
            <Wrapper innerRef = { this._ref }>
                { this._maybeRenderLoadingIndicator() }
            </Wrapper>
        );
    }

    /**
     * Load the conference by creating the iframe element in this component
     * and attaching utils from jitsi-meet-electron-utils.
     *
     * @returns {void}
     */
    _loadConference() {
        const url = new URL(this._conference.room, this._conference.serverURL);
        const roomName = url.pathname.split('/').pop();
        const host = this._conference.serverURL.replace(/https?:\/\//, '');
        const searchParameters = Object.fromEntries(url.searchParams);
        const urlParameters = Object.keys(searchParameters).length ? searchParameters : {};

        const configOverwrite = {
            startWithAudioMuted: this.props._startWithAudioMuted,
            startWithVideoMuted: this.props._startWithVideoMuted
        };

        const options = {
            configOverwrite,
            onload: this._onIframeLoad,
            parentNode: this._ref.current,
            roomName
        };

        this._api = new JitsiMeetExternalAPI(host, {
            ...options,
            ...urlParameters
        });

        this._api.on('suspendDetected', this._onVideoConferenceEnded);
        this._api.on('readyToClose', this._onVideoConferenceEnded);
        this._api.on('videoConferenceJoined',
            (conferenceInfo: Object) => {
                this.props.dispatch(conferenceJoined(this._conference));
                this._onVideoConferenceJoined(conferenceInfo);
            }
        );

        const { RemoteControl,
            setupScreenSharingRender,
            setupAlwaysOnTopRender,
            initPopupsConfigurationRender,
            setupWiFiStats,
            setupPowerMonitorRender
        } = window.jitsiNodeAPI.jitsiMeetElectronUtils;

        initPopupsConfigurationRender(this._api);

        const iframe = this._api.getIFrame();

        setupScreenSharingRender(this._api);
        new RemoteControl(iframe); // eslint-disable-line no-new

        // Allow window to be on top if enabled in settings
        if (this.props._alwaysOnTopWindowEnabled) {
            setupAlwaysOnTopRender(this._api);
        }

        setupWiFiStats(iframe);
        setupPowerMonitorRender(this._api);
    }

    /**
     * It renders a loading indicator, if appropriate.
     *
     * @returns {?ReactElement}
     */
    _maybeRenderLoadingIndicator() {
        if (this.state.isLoading) {
            return (
                <LoadingIndicator>
                    <Spinner size = 'large' />
                </LoadingIndicator>
            );
        }
    }

    /**
     * Navigates to home screen (Welcome).
     *
     * @param {Event} event - Event by which the function is called.
     * @param {string} room - Room name.
     * @param {string} serverURL - Server URL.
     * @returns {void}
     */
    _navigateToHome(event: Event, room: ?string, serverURL: ?string) {
        this.props.dispatch(push('/', {
            error: event.type === 'error',
            room,
            serverURL
        }));
    }

    _onVideoConferenceEnded: (*) => void;

    /**
     * Dispatches conference ended and navigates to home screen.
     *
     * @param {Event} event - Event by which the function is called.
     * @returns {void}
     * @private
     */
    _onVideoConferenceEnded(event: Event) {
        this.props.dispatch(conferenceEnded(this._conference));
        this._navigateToHome(event);
    }

    /**
     * Updates redux state's user name from conference.
     *
     * @param {Object} params - Returned object from event.
     * @param {string} id - Local Participant ID.
     * @returns {void}
     */
    _onDisplayNameChange(params: Object, id: string) {
        if (params.id === id) {
            this.props.dispatch(setName(params.displayname));
        }
    }

    /**
     * Updates redux state's email from conference.
     *
     * @param {Object} params - Returned object from event.
     * @param {string} id - Local Participant ID.
     * @returns {void}
     */
    _onEmailChange(params: Object, id: string) {
        if (params.id === id) {
            this.props.dispatch(setEmail(params.email));
        }
    }

    _onIframeLoad: (*) => void;

    /**
     * Sets state of loading to false when iframe has completely loaded.
     *
     * @returns {void}
     */
    _onIframeLoad() {
        if (this._loadTimer) {
            clearTimeout(this._loadTimer);
            this._loadTimer = null;
        }

        this.setState({
            isLoading: false
        });
    }

    /**
     * Saves conference info on joining it.
     *
     * @param {Object} conferenceInfo - Contains information about the current
     * conference.
     * @returns {void}
     */
    _onVideoConferenceJoined(conferenceInfo: Object) {
        this._setEmail(this.props._email);
        this._setName(this.props._name);

        const { id } = conferenceInfo;

        this._api.on('displayNameChange',
            (params: Object) => this._onDisplayNameChange(params, id));
        this._api.on('emailChange',
            (params: Object) => this._onEmailChange(params, id));
    }

    /**
     * Set email from settings to conference.
     *
     * @param {string} email - Email of user.
     * @returns {void}
     */
    _setEmail(email: string) {
        this._api.executeCommand('email', email);
    }

    /**
     * Set name from settings to conference.
     *
     * @param {string} name - Name of user.
     * @returns {void}
     */
    _setName(name: string) {
        this._api.executeCommand('displayName', name);
    }

}

/**
 * Maps (parts of) the redux state to the React props.
 *
 * @param {Object} state - The redux state.
 * @returns {Props}
 */
function _mapStateToProps(state: Object) {
    return {
        _alwaysOnTopWindowEnabled: getSetting(state, 'alwaysOnTopWindowEnabled', true),
        _email: state.settings.email,
        _name: state.settings.name,
        _serverURL: state.settings.serverURL,
        _serverTimeout: state.settings.serverTimeout,
        _startWithAudioMuted: state.settings.startWithAudioMuted,
        _startWithVideoMuted: state.settings.startWithVideoMuted
    };
}

export default connect(_mapStateToProps)(Conference);
<commit_msg>Open the conference with the app locale<commit_after>// @flow

import Spinner from '@atlaskit/spinner';

import React, { Component } from 'react';
import type { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';

import i18n from '../../../i18n';
import config from '../../config';
import { getSetting, setEmail, setName } from '../../settings';

import { conferenceEnded, conferenceJoined } from '../actions';
import JitsiMeetExternalAPI from '../external_api';
import { LoadingIndicator, Wrapper } from '../styled';

type Props = {

    /**
     * Redux dispatch.
     */
    dispatch: Dispatch<*>;

    /**
     * React Router location object.
     */
    location: Object;

    /**
     * AlwaysOnTop Window Enabled.
     */
    _alwaysOnTopWindowEnabled: boolean;

    /**
     * Email of user.
     */
    _email: string;

    /**
     * Name of user.
     */
    _name: string;

    /**
     * Default Jitsi Server URL.
     */
    _serverURL: string;

    /**
     * Default Jitsi Server Timeout.
     */
    _serverTimeout: number;

    /**
     * Start with Audio Muted.
     */
    _startWithAudioMuted: boolean;

    /**
     * Start with Video Muted.
     */
    _startWithVideoMuted: boolean;
};

type State = {

    /**
     * If the conference is loading or not.
     */
    isLoading: boolean;
};

/**
 * Conference component.
 */
class Conference extends Component<Props, State> {
    /**
     * External API object.
     */
    _api: Object;

    /**
     * Conference Object.
     */
    _conference: Object;

    /**
     * Timer to cancel the joining if it takes too long.
     */
    _loadTimer: ?TimeoutID;

    /**
     * Reference to the element of this component.
     */
    _ref: Object;

    /**
     * Initializes a new {@code Conference} instance.
     *
     * @inheritdoc
     */
    constructor() {
        super();

        this.state = {
            isLoading: true
        };

        this._ref = React.createRef();

        this._onIframeLoad = this._onIframeLoad.bind(this);
        this._onVideoConferenceEnded = this._onVideoConferenceEnded.bind(this);
    }

    /**
     * Attach the script to this component.
     *
     * @returns {void}
     */
    componentDidMount() {
        const room = this.props.location.state.room;
        const serverTimeout = this.props._serverTimeout || config.defaultServerTimeout;
        const serverURL = this.props.location.state.serverURL
            || this.props._serverURL
            || config.defaultServerURL;

        this._conference = {
            room,
            serverURL
        };

        this._loadConference();

        // Set a timer for a timeout duration, if we haven't loaded the iframe by then,
        // give up.
        this._loadTimer = setTimeout(() => {
            this._navigateToHome(

                // $FlowFixMe
                {
                    error: 'Loading error',
                    type: 'error'
                },
                room,
                serverURL);
        }, serverTimeout * 1000);
    }

    /**
     * Keep profile settings in sync with Conference.
     *
     * @param {Props} prevProps - Component's prop values before update.
     * @returns {void}
     */
    componentDidUpdate(prevProps) {
        const { props } = this;

        if (props._email !== prevProps._email) {
            this._setEmail(props._email);
        }
        if (props._name !== prevProps._name) {
            this._setName(props._name);
        }
    }

    /**
     * Remove conference on unmounting.
     *
     * @returns {void}
     */
    componentWillUnmount() {
        if (this._loadTimer) {
            clearTimeout(this._loadTimer);
        }
        if (this._api) {
            this._api.dispose();
        }
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @returns {ReactElement}
     */
    render() {
        return (
            <Wrapper innerRef = { this._ref }>
                { this._maybeRenderLoadingIndicator() }
            </Wrapper>
        );
    }

    /**
     * Load the conference by creating the iframe element in this component
     * and attaching utils from jitsi-meet-electron-utils.
     *
     * @returns {void}
     */
    _loadConference() {
        const url = new URL(this._conference.room, this._conference.serverURL);
        const roomName = url.pathname.split('/').pop();
        const host = this._conference.serverURL.replace(/https?:\/\//, '');
        const searchParameters = Object.fromEntries(url.searchParams);
        const locale = { lng: i18n.language };
        const urlParameters = {
            ...searchParameters,
            ...locale
        };

        const configOverwrite = {
            startWithAudioMuted: this.props._startWithAudioMuted,
            startWithVideoMuted: this.props._startWithVideoMuted
        };

        const options = {
            configOverwrite,
            onload: this._onIframeLoad,
            parentNode: this._ref.current,
            roomName
        };

        this._api = new JitsiMeetExternalAPI(host, {
            ...options,
            ...urlParameters
        });

        this._api.on('suspendDetected', this._onVideoConferenceEnded);
        this._api.on('readyToClose', this._onVideoConferenceEnded);
        this._api.on('videoConferenceJoined',
            (conferenceInfo: Object) => {
                this.props.dispatch(conferenceJoined(this._conference));
                this._onVideoConferenceJoined(conferenceInfo);
            }
        );

        const { RemoteControl,
            setupScreenSharingRender,
            setupAlwaysOnTopRender,
            initPopupsConfigurationRender,
            setupWiFiStats,
            setupPowerMonitorRender
        } = window.jitsiNodeAPI.jitsiMeetElectronUtils;

        initPopupsConfigurationRender(this._api);

        const iframe = this._api.getIFrame();

        setupScreenSharingRender(this._api);
        new RemoteControl(iframe); // eslint-disable-line no-new

        // Allow window to be on top if enabled in settings
        if (this.props._alwaysOnTopWindowEnabled) {
            setupAlwaysOnTopRender(this._api);
        }

        setupWiFiStats(iframe);
        setupPowerMonitorRender(this._api);
    }

    /**
     * It renders a loading indicator, if appropriate.
     *
     * @returns {?ReactElement}
     */
    _maybeRenderLoadingIndicator() {
        if (this.state.isLoading) {
            return (
                <LoadingIndicator>
                    <Spinner size = 'large' />
                </LoadingIndicator>
            );
        }
    }

    /**
     * Navigates to home screen (Welcome).
     *
     * @param {Event} event - Event by which the function is called.
     * @param {string} room - Room name.
     * @param {string} serverURL - Server URL.
     * @returns {void}
     */
    _navigateToHome(event: Event, room: ?string, serverURL: ?string) {
        this.props.dispatch(push('/', {
            error: event.type === 'error',
            room,
            serverURL
        }));
    }

    _onVideoConferenceEnded: (*) => void;

    /**
     * Dispatches conference ended and navigates to home screen.
     *
     * @param {Event} event - Event by which the function is called.
     * @returns {void}
     * @private
     */
    _onVideoConferenceEnded(event: Event) {
        this.props.dispatch(conferenceEnded(this._conference));
        this._navigateToHome(event);
    }

    /**
     * Updates redux state's user name from conference.
     *
     * @param {Object} params - Returned object from event.
     * @param {string} id - Local Participant ID.
     * @returns {void}
     */
    _onDisplayNameChange(params: Object, id: string) {
        if (params.id === id) {
            this.props.dispatch(setName(params.displayname));
        }
    }

    /**
     * Updates redux state's email from conference.
     *
     * @param {Object} params - Returned object from event.
     * @param {string} id - Local Participant ID.
     * @returns {void}
     */
    _onEmailChange(params: Object, id: string) {
        if (params.id === id) {
            this.props.dispatch(setEmail(params.email));
        }
    }

    _onIframeLoad: (*) => void;

    /**
     * Sets state of loading to false when iframe has completely loaded.
     *
     * @returns {void}
     */
    _onIframeLoad() {
        if (this._loadTimer) {
            clearTimeout(this._loadTimer);
            this._loadTimer = null;
        }

        this.setState({
            isLoading: false
        });
    }

    /**
     * Saves conference info on joining it.
     *
     * @param {Object} conferenceInfo - Contains information about the current
     * conference.
     * @returns {void}
     */
    _onVideoConferenceJoined(conferenceInfo: Object) {
        this._setEmail(this.props._email);
        this._setName(this.props._name);

        const { id } = conferenceInfo;

        this._api.on('displayNameChange',
            (params: Object) => this._onDisplayNameChange(params, id));
        this._api.on('emailChange',
            (params: Object) => this._onEmailChange(params, id));
    }

    /**
     * Set email from settings to conference.
     *
     * @param {string} email - Email of user.
     * @returns {void}
     */
    _setEmail(email: string) {
        this._api.executeCommand('email', email);
    }

    /**
     * Set name from settings to conference.
     *
     * @param {string} name - Name of user.
     * @returns {void}
     */
    _setName(name: string) {
        this._api.executeCommand('displayName', name);
    }

}

/**
 * Maps (parts of) the redux state to the React props.
 *
 * @param {Object} state - The redux state.
 * @returns {Props}
 */
function _mapStateToProps(state: Object) {
    return {
        _alwaysOnTopWindowEnabled: getSetting(state, 'alwaysOnTopWindowEnabled', true),
        _email: state.settings.email,
        _name: state.settings.name,
        _serverURL: state.settings.serverURL,
        _serverTimeout: state.settings.serverTimeout,
        _startWithAudioMuted: state.settings.startWithAudioMuted,
        _startWithVideoMuted: state.settings.startWithVideoMuted
    };
}

export default connect(_mapStateToProps)(Conference);
<|endoftext|>


<commit_before>import $ from 'jquery';
import ee from '../../shared/pub_sub';

export default class ProgressTracker {
  constructor() {
    this.addEventListeners();
  }

  addEventListeners() {
    const $header = $('.header-logo');
    ee.on('action:submitted_success', this.show);
    ee.on('action:submitted_success', () => this.tick('signed'));
    ee.on('fundraiser:transaction_success', () => this.tick('donated'));
    window.addEventListener(
      'share',
      () => {
        if ($('.overlay-visible').length > 0) {
          $header.hide();
        }
        this.tick('shared');
      },
      false
    );
    $('.two-step__decline').on('click', () => {
      if ($('.overlay-visible').length > 0) {
        $header.hide();
      }
      this.cross('shared');
    });
  }

  show() {
    const $header = $('.header-logo');
    const $tracker = $('.header-logo .progress-tracker');

    $header.addClass('with-progress-tracker');

    $tracker
      .removeClass('hidden-closed')
      .clone()
      .addClass('progress-tracker--fundraiser')
      .prependTo('.Stepper.fundraiser-bar__top');
  }

  tick(section) {
    $(`.progress-tracker__circle--${section}`)
      .removeClass('progress-tracker__circle--cross')
      .addClass('progress-tracker__circle--tick');
  }

  cross(section) {
    $(`.progress-tracker__circle--${section}`)
      .removeClass('progress-tracker__circle--tick')
      .addClass('progress-tracker__circle--cross');
  }
}
<commit_msg>Make progress bar javascript hide the two step component, whether it be share or donate.<commit_after>import $ from 'jquery';
import ee from '../../shared/pub_sub';

export default class ProgressTracker {
  constructor() {
    this.addEventListeners();
  }

  addEventListeners() {
    const $header = $('.header-logo');
    ee.on('action:submitted_success', this.show);
    ee.on('action:submitted_success', () => this.tick('signed'));
    ee.on('fundraiser:transaction_success', () => this.tick('donated'));
    window.addEventListener(
      'share',
      () => {
        if ($('.overlay-visible').length > 0) {
          $header.hide();
        }
        this.tick('shared');
      },
      false
    );
    $('.two-step__decline').on('click', () => {
      if ($('.overlay-visible').length > 0) {
        $header.hide();
      }
      $('[data-step="two"]')
        .removeClass('progress-tracker__circle--tick')
        .addClass('progress-tracker__circle--cross');
    });
  }

  show() {
    const $header = $('.header-logo');
    const $tracker = $('.header-logo .progress-tracker');

    $header.addClass('with-progress-tracker');

    $tracker
      .removeClass('hidden-closed')
      .clone()
      .addClass('progress-tracker--fundraiser')
      .prependTo('.Stepper.fundraiser-bar__top');
  }

  tick(section) {
    $(`.progress-tracker__circle--${section}`)
      .removeClass('progress-tracker__circle--cross')
      .addClass('progress-tracker__circle--tick');
  }

  cross(section) {
    $(`.progress-tracker__circle--${section}`)
      .removeClass('progress-tracker__circle--tick')
      .addClass('progress-tracker__circle--cross');
  }
}
<|endoftext|>


<commit_before>/**
 * @file BaseTable component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import ColGroup from '../_ColGroup';
import Thead from '../_Thead';
import Tbody from '../_Tbody';
import Tfoot from '../_Tfoot';

// Statics
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import classNames from 'classnames';
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';

class BaseTable extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    /* eslint-disable complexity */
    render() {

        const {

            className, style, data, value, hoverRow, idProp, baseColIndex, fixed, fragment, ignoreColumnWidth, scrollEl,
            columns, headColumns, bodyColumns, selectMode, selectAllMode, expandRows,
            isMouseEventForbidden, isHeadFixed, isFootFixed, isHeadHidden, isFootHidden,
            hasHeadRenderer, hasBodyRenderer, hasFootRenderer,
            sorting, defaultSortingType, sortingAscIconCls, sortingDescIconCls, isClickSorting,
            onRowHover, onSortChange, onExpandChange, onRequestColumnsSpan,

            ...restProps

        } = this.props;

        return (
            <table {...restProps}
                   className={classNames('base-table', {
                       [className]: className
                   })}
                   style={style}>

                <ColGroup columns={TC.getColumnsSpan(fragment, bodyColumns || columns)}
                          ignoreColumnWidth={ignoreColumnWidth}/>

                {
                    !isHeadHidden && hasHeadRenderer && (
                        fragment === TableFragment.HEAD
                        || (!fixed && !fragment)
                        || (!fragment && fixed && !isHeadFixed)
                    ) ?
                        <Thead {...restProps}
                               columns={headColumns || [columns]}
                               data={data}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               sorting={sorting}
                               defaultSortingType={defaultSortingType}
                               sortingAscIconCls={sortingAscIconCls}
                               sortingDescIconCls={sortingDescIconCls}
                               isClickSorting={isClickSorting}
                               scrollEl={scrollEl}
                               onSortChange={onSortChange}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

                {
                    !fragment && hasBodyRenderer ?
                        <Tbody {...restProps}
                               columns={bodyColumns || columns}
                               data={data}
                               value={value}
                               hoverRow={hoverRow}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               expandRows={expandRows}
                               idProp={idProp}
                               baseColIndex={baseColIndex}
                               sorting={sorting}
                               isMouseEventForbidden={isMouseEventForbidden}
                               scrollEl={scrollEl}
                               onExpandChange={onExpandChange}
                               onRowHover={onRowHover}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

                {/** render foot if a footRenderer exists in columns */}
                {
                    !isFootHidden && hasFootRenderer && (
                        fragment === TableFragment.FOOT
                        || (!fixed && !fragment)
                        || (!fragment && fixed && !isFootFixed)
                    ) ?
                        <Tfoot {...restProps}
                               columns={bodyColumns || columns}
                               data={data}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               scrollEl={scrollEl}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

            </table>
        );

    }
}

BaseTable.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

    fragment: PropTypes.oneOf(Util.enumerateValue(TableFragment)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })),
    headColumns: PropTypes.array,
    bodyColumns: PropTypes.array,

    data: PropTypes.array,
    value: PropTypes.array,
    hoverRow: PropTypes.object,
    idProp: PropTypes.string,
    baseColIndex: PropTypes.number,
    disabled: PropTypes.bool,
    expandRows: PropTypes.array,
    isMouseEventForbidden: PropTypes.bool,
    ignoreColumnWidth: PropTypes.bool,
    scrollEl: PropTypes.object,

    /**
     * fixed
     */
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * has renderer
     */
    hasHeadRenderer: PropTypes.bool,
    hasBodyRenderer: PropTypes.bool,
    hasFootRenderer: PropTypes.bool,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    isClickSorting: PropTypes.bool,

    /**
     * callback
     */
    onSortChange: PropTypes.func,
    onHeadClick: PropTypes.func,
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onFootClick: PropTypes.func,
    onRowHover: PropTypes.func,
    onExpandChange: PropTypes.func,
    onRequestColumnsSpan: PropTypes.func

};

BaseTable.defaultProps = {

    baseColIndex: 0,
    disabled: false,
    expandRows: [],
    isMouseEventForbidden: false,
    ignoreColumnWidth: false,

    /**
     * fixed
     */
    isHeadFixed: false,
    isFootFixed: false,

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * has renderer
     */
    hasHeadRenderer: true,
    hasBodyRenderer: true,
    hasFootRenderer: true,

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    isClickSorting: true

};

export default BaseTable;
<commit_msg>update BaseTable<commit_after>/**
 * @file BaseTable component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import ColGroup from '../_ColGroup';
import Thead from '../_Thead';
import Tbody from '../_Tbody';
import Tfoot from '../_Tfoot';

// Statics
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import classNames from 'classnames';
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';

class BaseTable extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColumnsSpan = () => {
        const {fragment, bodyColumns, columns, onRequestColumnsSpan} = this.props;
        return onRequestColumnsSpan ?
            onRequestColumnsSpan(fragment, bodyColumns || columns)
            :
            TC.getColumnsSpan(fragment, bodyColumns || columns);
    };

    /* eslint-disable complexity */
    render() {

        const {

            className, style, data, value, hoverRow, idProp, baseColIndex, fixed, fragment, ignoreColumnWidth, scrollEl,
            columns, headColumns, bodyColumns, selectMode, selectAllMode, expandRows,
            isMouseEventForbidden, isHeadFixed, isFootFixed, isHeadHidden, isFootHidden,
            hasHeadRenderer, hasBodyRenderer, hasFootRenderer,
            sorting, defaultSortingType, sortingAscIconCls, sortingDescIconCls, isClickSorting,
            onRowHover, onSortChange, onExpandChange, onRequestColumnsSpan,

            ...restProps

        } = this.props;

        return (
            <table {...restProps}
                   className={classNames('base-table', {
                       [className]: className
                   })}
                   style={style}>

                <ColGroup columns={this.getColumnsSpan()}
                          ignoreColumnWidth={ignoreColumnWidth}/>

                {
                    !isHeadHidden && hasHeadRenderer && (
                        fragment === TableFragment.HEAD
                        || (!fixed && !fragment)
                        || (!fragment && fixed && !isHeadFixed)
                    ) ?
                        <Thead {...restProps}
                               columns={headColumns || [columns]}
                               data={data}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               sorting={sorting}
                               defaultSortingType={defaultSortingType}
                               sortingAscIconCls={sortingAscIconCls}
                               sortingDescIconCls={sortingDescIconCls}
                               isClickSorting={isClickSorting}
                               scrollEl={scrollEl}
                               onSortChange={onSortChange}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

                {
                    !fragment && hasBodyRenderer ?
                        <Tbody {...restProps}
                               columns={bodyColumns || columns}
                               data={data}
                               value={value}
                               hoverRow={hoverRow}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               expandRows={expandRows}
                               idProp={idProp}
                               baseColIndex={baseColIndex}
                               sorting={sorting}
                               isMouseEventForbidden={isMouseEventForbidden}
                               scrollEl={scrollEl}
                               onExpandChange={onExpandChange}
                               onRowHover={onRowHover}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

                {/** render foot if a footRenderer exists in columns */}
                {
                    !isFootHidden && hasFootRenderer && (
                        fragment === TableFragment.FOOT
                        || (!fixed && !fragment)
                        || (!fragment && fixed && !isFootFixed)
                    ) ?
                        <Tfoot {...restProps}
                               columns={bodyColumns || columns}
                               data={data}
                               selectMode={selectMode}
                               selectAllMode={selectAllMode}
                               scrollEl={scrollEl}
                               onRequestColumnsSpan={onRequestColumnsSpan}/>
                        :
                        null
                }

            </table>
        );

    }
}

BaseTable.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

    fragment: PropTypes.oneOf(Util.enumerateValue(TableFragment)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })),
    headColumns: PropTypes.array,
    bodyColumns: PropTypes.array,

    data: PropTypes.array,
    value: PropTypes.array,
    hoverRow: PropTypes.object,
    idProp: PropTypes.string,
    baseColIndex: PropTypes.number,
    disabled: PropTypes.bool,
    expandRows: PropTypes.array,
    isMouseEventForbidden: PropTypes.bool,
    ignoreColumnWidth: PropTypes.bool,
    scrollEl: PropTypes.object,

    /**
     * fixed
     */
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * has renderer
     */
    hasHeadRenderer: PropTypes.bool,
    hasBodyRenderer: PropTypes.bool,
    hasFootRenderer: PropTypes.bool,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    isClickSorting: PropTypes.bool,

    /**
     * callback
     */
    onSortChange: PropTypes.func,
    onHeadClick: PropTypes.func,
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onFootClick: PropTypes.func,
    onRowHover: PropTypes.func,
    onExpandChange: PropTypes.func,
    onRequestColumnsSpan: PropTypes.func

};

BaseTable.defaultProps = {

    baseColIndex: 0,
    disabled: false,
    expandRows: [],
    isMouseEventForbidden: false,
    ignoreColumnWidth: false,

    /**
     * fixed
     */
    isHeadFixed: false,
    isFootFixed: false,

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * has renderer
     */
    hasHeadRenderer: true,
    hasBodyRenderer: true,
    hasFootRenderer: true,

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    isClickSorting: true

};

export default BaseTable;
<|endoftext|>


<commit_before>#!/usr/bin/env node
var program = require('commander');
var Excel = require("exceljs");
var fs = require('fs');
var gutil = require('gulp-util');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var	gulp = require('gulp');
var jsonfile = require('jsonfile');
var _ = require('underscore');
var configuration = require('./config.js');
var styles = configuration.styles;
var config = configuration.config;

// cli
program
	.option('-o, --exportFile <excelExportFile>', 'The file name to export the excel file to')
	.option('-i, --messages <messagesFolder>', 'The directory where the json files are located')
	.option('-n, --messages <numberOfLanguages>', 'The number of languages you want to translate')
	.parse(process.argv);

// if a file has been specified use it here
var optionalConfigFile;
try {
	optionalConfigFile = jsonfile.readFileSync(configuration.optionalConfigFileName)
}catch(e) {}

if (!optionalConfigFile && (!program.exportFile || !program.messages)) {
	gutil.log(gutil.colors.bgRed('missing required arguments ... run --help'));
	return;
}

var paths = {
	excelExport: program.excelExportFile || optionalConfigFile.excelExportFile, //'mercury-translations.xlsx',
	messagesDir: './' + (program.messagesFolder || optionalConfigFile.messagesFolder) ,//'./Client/messages/'
};

var numOfLangs = (program.numberOfLanguages || optionalConfigFile.numberOfLanguages) || 2;

function writeXLSX(callback){

	// instead of hardcoding the languages we can infer them from the folder names in the messages folder
	var languages = fs.readdirSync(paths.messagesDir);

	// filter out any hidden folders like .DS_STORE
	languages = _.filter(languages, function(key) {return key.charAt(0) !== '.'});

	// add a new excel workbook that will eventually be exported
	var workbook = new Excel.Workbook();

	// adding worksheets to the excel document
	var worksheets = [];

	var columns = config.baseColumns;
	var translations = {};

	for (var i = 0; i < languages.length; i++) {
		var language = languages[i];
		translations[language] = {};

		// reading all the names in language directory
		var thisTranslationDirectory = paths.messagesDir + language + '/';

		var translationFiles = fs.readdirSync(thisTranslationDirectory);
		// filter out any hidden files names like .DS_STORE
		translationFiles = _.filter(translationFiles, function(key) {return key.charAt(0) !== '.'});

		for(var fileIndex = 0 ; fileIndex < translationFiles.length; fileIndex++){
			var translationFile = translationFiles[fileIndex]; // HOME_PAGE.json
			var translationFileKey = translationFile.split(".")[0]; // HOME_PAGE

			var filepath = thisTranslationDirectory + translationFile;
			translations[language] = jsonfile.readFileSync(filepath, null);

			var pageNames = Object.keys(translations[language]);
			// add the name of this key to the worksheets
			worksheets = _.union(worksheets, pageNames);
		}

		columns.push({
			header: language,
			key: language,
			width: 50,
			style: styles.cellTranslation
		});
	}

	for (var i in worksheets) {
		workbook.addWorksheet(worksheets[i]);
	}

	var duplicatedKeys = [];

	function addRow(worksheet, page, section, key){
		var row = {page: page, section: section, key: key};
		var item = translations[page][section][key];

		// alter the row data if this is a less nested item
		if (typeof item === "string"){
			item = translations[page][section];
			row.section = "";
			row.key = section;
		}

		for (var language in item) {
			row[language] = item[language];
		}
		worksheet.addRow(row);
	}

	workbook.eachSheet(function(worksheet, sheetId) {
		worksheet.columns = columns;
		worksheet.getRow(1).font = styles.header.font;
		worksheet.getRow(1).fill = styles.header.fill;
		worksheet.getRow(1).border = styles.header.border;
	});

	// convert the structure from
	// language
	//     |_ page
	//          |_ section
	//                 |_key
	//                     |_ value
	//
	// to...
	//
	//  page
	//   |_ section
	//         |_key
	//             |_language
	//                  |_ value

	var tmp = {};
	for (var language in translations) {
		for (var page in translations[language]) {
			tmp[page] = tmp[page] || {};
			var worksheet = workbook.getWorksheet(page);
			for (var section in translations[language][page]) {
				tmp[page][section] = tmp[page][section] || {};

				// this is in the event that the .json is two levels deep (i.e. there is no real section)
				if (typeof translations[language][page][section] === "string"){
					tmp[page][section][language] = translations[language][page][section];
					continue;
				}

				for (var key in translations[language][page][section]){
					tmp[page][section][key] = tmp[page][section][key] || {};
					tmp[page][section][key][language] = translations[language][page][section][key];

				}
			}
		}
	}

	translations = tmp;

	for (var page in translations) {
		var worksheet = workbook.getWorksheet(page);
		for (var section in translations[page]) {
			for (var key in translations[page][section]){
				if (duplicatedKeys.indexOf(section) === -1) {
					addRow(worksheet, page, section, key);
					if (typeof translations[page][section][key] === "string") {
						duplicatedKeys.push(section);
					}
				}
			}
		}
	}

	// color rows that have missing information
	workbook.eachSheet(function(worksheet, sheetId) {
		worksheet.eachRow(function(row, rowNumber) {
			for (var i = columns.length - numOfLangs; i <= columns.length; i++){
				if (!row.values[i]){
					worksheet.getRow(rowNumber).fill = styles.emptyRow.fill;
					break;
				}
			}
		});
	});

	workbook.xlsx.writeFile(paths.excelExport).then(function(){
		callback(paths.excelExport);
	});
}

writeXLSX(function(translation){
	gutil.log(gutil.colors.green('Success') +' - Translations exported to ' + gutil.colors.magenta('~'+paths.excelExport));
});

module.exports = {
	writeXLSX : writeXLSX
};
<commit_msg>fixes accroding to comments<commit_after>#!/usr/bin/env node
var program = require('commander');
var Excel = require("exceljs");
var fs = require('fs');
var gutil = require('gulp-util');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var	gulp = require('gulp');
var jsonfile = require('jsonfile');
var _ = require('underscore');
var configuration = require('./config.js');
var styles = configuration.styles;
var config = configuration.config;

// cli
program
	.option('-o, --exportFile <excelExportFile>', 'The file name to export the excel file to')
	.option('-i, --messages <messagesFolder>', 'The directory where the json files are located')
	.option('-n, --messages <numberOfLanguages>', 'The number of languages you want to translate')
	.parse(process.argv);

// if a file has been specified use it here
var optionalConfigFile;
try {
	optionalConfigFile = jsonfile.readFileSync(configuration.optionalConfigFileName)
}catch(e) {}

if (!optionalConfigFile && (!program.exportFile || !program.messages)) {
	gutil.log(gutil.colors.bgRed('missing required arguments ... run --help'));
	return;
}

var paths = {
	excelExport: program.excelExportFile || optionalConfigFile.excelExportFile, //'mercury-translations.xlsx',
	messagesDir: './' + (program.messagesFolder || optionalConfigFile.messagesFolder) ,//'./Client/messages/'
};

function writeXLSX(callback){

	// instead of hardcoding the languages we can infer them from the folder names in the messages folder
	var languages = fs.readdirSync(paths.messagesDir);

	// filter out any hidden folders like .DS_STORE
	languages = _.filter(languages, function(key) {return key.charAt(0) !== '.'});

	var numOfLangs = (program.numberOfLanguages || optionalConfigFile.numberOfLanguages) || languages.length || 2;

	// add a new excel workbook that will eventually be exported
	var workbook = new Excel.Workbook();

	// adding worksheets to the excel document
	var worksheets = [];

	var columns = config.baseColumns;
	var translations = {};

	for (var i = 0; i < languages.length; i++) {
		var language = languages[i];
		translations[language] = {};

		// reading all the names in language directory
		var thisTranslationDirectory = paths.messagesDir + language + '/';

		var translationFiles = fs.readdirSync(thisTranslationDirectory);
		// filter out any hidden files names like .DS_STORE
		translationFiles = _.filter(translationFiles, function(key) {return key.charAt(0) !== '.'});

		for(var fileIndex = 0 ; fileIndex < translationFiles.length; fileIndex++){
			var translationFile = translationFiles[fileIndex]; // HOME_PAGE.json
			var translationFileKey = translationFile.split(".")[0]; // HOME_PAGE

			var filepath = thisTranslationDirectory + translationFile;
			translations[language] = jsonfile.readFileSync(filepath, null);

			var pageNames = Object.keys(translations[language]);
			// add the name of this key to the worksheets
			worksheets = _.union(worksheets, pageNames);
		}

		columns.push({
			header: language,
			key: language,
			width: 50,
			style: styles.cellTranslation
		});
	}

	for (var i in worksheets) {
		workbook.addWorksheet(worksheets[i]);
	}

	var duplicatedKeys = [];

	function addRow(worksheet, page, section, key){
		var row = {page: page, section: section, key: key};
		var item = translations[page][section][key];

		// alter the row data if this is a less nested item
		if (typeof item === "string"){
			item = translations[page][section];
			row.section = "";
			row.key = section;
		}

		for (var language in item) {
			row[language] = item[language];
		}
		worksheet.addRow(row);
	}

	workbook.eachSheet(function(worksheet, sheetId) {
		worksheet.columns = columns;
		worksheet.getRow(1).font = styles.header.font;
		worksheet.getRow(1).fill = styles.header.fill;
		worksheet.getRow(1).border = styles.header.border;
	});

	// convert the structure from
	// language
	//     |_ page
	//          |_ section
	//                 |_key
	//                     |_ value
	//
	// to...
	//
	//  page
	//   |_ section
	//         |_key
	//             |_language
	//                  |_ value

	var tmp = {};
	for (var language in translations) {
		for (var page in translations[language]) {
			tmp[page] = tmp[page] || {};
			var worksheet = workbook.getWorksheet(page);
			for (var section in translations[language][page]) {
				tmp[page][section] = tmp[page][section] || {};

				// this is in the event that the .json is two levels deep (i.e. there is no real section)
				if (typeof translations[language][page][section] === "string"){
					tmp[page][section][language] = translations[language][page][section];
					continue;
				}

				for (var key in translations[language][page][section]){
					tmp[page][section][key] = tmp[page][section][key] || {};
					tmp[page][section][key][language] = translations[language][page][section][key];

				}
			}
		}
	}

	translations = tmp;

	for (var page in translations) {
		var worksheet = workbook.getWorksheet(page);
		for (var section in translations[page]) {
			for (var key in translations[page][section]){
				if (duplicatedKeys.indexOf(section) === -1) {
					addRow(worksheet, page, section, key);
					if (typeof translations[page][section][key] === "string") {
						duplicatedKeys.push(section);
					}
				}
			}
		}
	}

	// color rows that have missing information
	workbook.eachSheet(function(worksheet, sheetId) {
		worksheet.eachRow(function(row, rowNumber) {
			for (var i = columns.length - numOfLangs; i <= columns.length; i++){
				if (!row.values[i]){
					worksheet.getRow(rowNumber).fill = styles.emptyRow.fill;
					break;
				}
			}
		});
	});

	workbook.xlsx.writeFile(paths.excelExport).then(function(){
		callback(paths.excelExport);
	});
}

writeXLSX(function(translation){
	gutil.log(gutil.colors.green('Success') +' - Translations exported to ' + gutil.colors.magenta('~'+paths.excelExport));
});

module.exports = {
	writeXLSX : writeXLSX
};
<|endoftext|>


<commit_before>(function() {
  'use strict';

  /**
   * @ngdoc function
   * @name  app.login:MessagesFormCtrl
   * @description
   * # MessagesFormCtrl
   * A module to manage messages sending
   */
  angular.module('app.messages')
    .controller('MessagesFormCtrl', MessagesFormCtrl);

  /* @ngInject */
  function MessagesFormCtrl($state, messagesService) {

    var vm = this;

    vm.send = send;

    return vm;

    function send(telephone, body) {
      var messageObject = {
        to: '00' + telephone,
        message: body
      }
      messagesService.send(messageObject);
    }

  }

})();
<commit_msg>bugfix<commit_after>(function() {
  'use strict';

  /**
   * @ngdoc function
   * @name  app.login:MessagesFormCtrl
   * @description
   * # MessagesFormCtrl
   * A module to manage messages sending
   */
  angular.module('app.messages')
    .controller('MessagesFormCtrl', MessagesFormCtrl);

  /* @ngInject */
  function MessagesFormCtrl($state, messagesService) {

    var vm = this;

    vm.send = send;

    return vm;

    function send(telephone, body) {
      var messageObject = {
        to: '00' + telephone,
        message: body
      };
      messagesService.send(messageObject);
    }

  }

})();
<|endoftext|>