<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.search = {
	setup: function() {
		var opts = {
			autoFocus: true,
			minLength: 0,
			source: function(request, response) {
				var txt = strip(request.term);
				frappe.search.options = [];
				if(!txt) {
					// search recent
					frappe.search.verbs[1]("");
				} else {
					var lower = strip(txt.toLowerCase());
					$.each(frappe.search.verbs, function(i, action) {
						action(lower);
					});
				}

				// sort options
				frappe.search.options.sort(function(a, b) {
					return (a.match || "").length - (b.match || "").length; });

				frappe.search.add_help();

				response(frappe.search.options);
			},
			open: function() {
				frappe.search.autocomplete_open = true;
			},
			close: function() {
				frappe.search.autocomplete_open = false;
			},
			focus: function(event, ui) {
				return false;
			},
			select: function(event, ui) {
				if(ui.item.route_options) {
					frappe.route_options = ui.item.route_options;
				}

				if(ui.item.onclick) {
					ui.item.onclick(ui.item.match);
				} else {
					frappe.set_route(ui.item.route);
				}
				$(this).val('');
				return false;
			}
		};

		var render_item = function(ul, d) {
			var html = "" + __(d.value) + "";
			if(d.description && d.value!==d.description) {
				html += '
' + __(d.description) + '';
			}
			return $('

')
				.data('item.autocomplete', d)
				.html('
' + html + '
')
				.appendTo(ul);
		};

		var open_recent = function() {
			if (!frappe.search.autocomplete_open) {
				$(this).autocomplete("search", "");
			}
		}

		$("#navbar-search")
			.on("focus", open_recent)
			.autocomplete(opts).data('ui-autocomplete')._renderItem = render_item;

		$("#sidebar-search")
			.on("focus", open_recent)
			.autocomplete(opts).data('ui-autocomplete')._renderItem = render_item;

		frappe.search.make_page_title_map();
		frappe.search.setup_recent();
	},
	add_help: function() {
		frappe.search.options.push({
			value: __("Help on Search"),
			onclick: function() {
				var txt = '
\

'+__("Make a new record")+'	'+
						__("new type of document")+'
\

'+__("List a document type")+'	'+
						__("document type..., e.g. customer")+'
\

'+__("Search in a document type")+'	'+
						__("text in document type")+'
\

'+__("Open a module or tool")+'	'+
						__("module name...")+'
\

'+__("Calculate")+'	'+
						__("e.g. (55 + 434) / 4 or =Math.sin(Math.PI/2)...")+'
\

'
				msgprint(txt, "Search Help");
			}
		});
	},
	make_page_title_map: function() {
		frappe.search.pages = {};
		$.each(frappe.boot.page_info, function(name, p) {
			frappe.search.pages[p.title] = p;
			p.name = name;
		});
	},
	setup_recent: function() {
		var recent = JSON.parse(frappe.boot.user.recent || "[]");
		frappe.search.recent = {};
		for (var i=0, l=recent.length; i < l; i++) {
			var d = recent[i];
			if (!frappe.search.recent[d[0]]) {
				frappe.search.recent[d[0]] = [];
			}
			frappe.search.recent[d[0]].push(d[1]);
		}
	},
	find: function(list, txt, process) {
		$.each(list, function(i, item) {
			_item = __(item).toLowerCase().replace(/-/g, " ");
			if(txt===_item || _item.indexOf(txt) !== -1) {
				var option = process(item);
				option.match = item;
				frappe.search.options.push(option);
			}
		});
	}
}

frappe.search.verbs = [
	// search in list if current
	function(txt) {
		var route = frappe.get_route();
		if(route[0]==="List" && txt.indexOf(" in") === -1) {
			// search in title field
			var meta = frappe.get_meta(frappe.container.page.doclistview.doctype);
			var search_field = meta.title_field || "name";
			var options = {};
			options[search_field] = ["like", "%" + txt + "%"];
			frappe.search.options.push({
				value: __('Find {0} in {1}', [""+txt+"", "" + route[1] + ""]),
				route_options: options,
				onclick: function() {
					frappe.container.page.doclistview.set_route_options();
				},
				match: txt
			});
		}
	},

	// recent
	function(txt) {
		var doctypes = frappe.utils.unique(keys(locals).concat(keys(frappe.search.recent)));
		for(var i in doctypes) {
			var doctype = doctypes[i];
			if(doctype[0]!==":" && !frappe.model.is_table(doctype)
				&& !in_list(frappe.boot.single_types, doctype)
				&& !in_list(["DocType", "DocField", "DocPerm", "Page", "Country", "Currency", "Page Role"], doctype)) {
				var values = frappe.utils.unique(keys(locals[doctype]).concat(frappe.search.recent[doctype] || []));
				var ret = frappe.search.find(values, txt, function(match) {
					return {
						value: __(doctype) + " " + match + "",
						route: ["Form", doctype, match]
					}
				});
			}
		}
	},

	// new doc
	function(txt) {
		var ret = false;
		if(txt.split(" ")[0]==="new") {
			frappe.search.find(frappe.boot.user.can_create, txt.substr(4), function(match) {
				return {
					value:__("New {0}", [""+match+""]),
					onclick: function() { new_doc(match); }
				}
			});
		}
	},

	// doctype list
	function(txt) {
		frappe.search.find(frappe.boot.user.can_read, txt, function(match) {
			if(in_list(frappe.boot.single_types, match)) {
				return {
					value: __("{0}", [""+__(match)+""]),
					route:["Form", match, match]
				}
			} else {
				return {
					value: __("{0} List", [""+__(match)+""]),
					route:["List", match]
				}
			}
		});
	},

	// pages
	function(txt) {
		frappe.search.find(keys(frappe.search.pages), txt, function(match) {
			return {
				value: __("Open {0}", [""+__(match)+""]),
				route: [frappe.search.pages[match].route || frappe.search.pages[match].name]
			}
		});
	},

	// modules
	function(txt) {
		frappe.search.find(keys(frappe.modules), txt, function(match) {
			ret = {
				value: __("Open {0}", [""+__(match)+""]),
			}
			if(frappe.modules[match].link) {
				ret.route = [frappe.modules[match].link];
			} else {
				ret.route = ["Module", match];
			}
			return ret;
		});
	},

	// in
	function(txt) {
		if(in_list(txt.split(" "), "in")) {
			parts = txt.split(" in ");
			frappe.search.find(frappe.boot.user.can_read, parts[1], function(match) {
				return {
					value: __('Find {0} in {1}', [""+__(parts[0])+"", ""+__(match)+""]),
					route_options: {"name": ["like", "%" + parts[0] + "%"]},
					route: ["List", match]
				}
			});
		}
	},

	// calculator
	function(txt) {
		var first = txt.substr(0,1);
		if(first==parseInt(first) || first==="(" || first==="=") {
			if(first==="=") {
				txt = txt.substr(1);
			}

			try {
				var val = eval(txt);
				var formatted_value = $.format('{0} = {1}', [txt, ""+val+""]);
				frappe.search.options.push({
					value: formatted_value,
					match: val,
					onclick: function(match) {
						msgprint(formatted_value, "Result");
					}
				});
			} catch(e) {
				// pass
			}

		};
	},
];
<commit_msg>[awesome bar] ignore print format<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.search = {
	setup: function() {
		var opts = {
			autoFocus: true,
			minLength: 0,
			source: function(request, response) {
				var txt = strip(request.term);
				frappe.search.options = [];
				if(!txt) {
					// search recent
					frappe.search.verbs[1]("");
				} else {
					var lower = strip(txt.toLowerCase());
					$.each(frappe.search.verbs, function(i, action) {
						action(lower);
					});
				}

				// sort options
				frappe.search.options.sort(function(a, b) {
					return (a.match || "").length - (b.match || "").length; });

				frappe.search.add_help();

				response(frappe.search.options);
			},
			open: function() {
				frappe.search.autocomplete_open = true;
			},
			close: function() {
				frappe.search.autocomplete_open = false;
			},
			focus: function(event, ui) {
				return false;
			},
			select: function(event, ui) {
				if(ui.item.route_options) {
					frappe.route_options = ui.item.route_options;
				}

				if(ui.item.onclick) {
					ui.item.onclick(ui.item.match);
				} else {
					frappe.set_route(ui.item.route);
				}
				$(this).val('');
				return false;
			}
		};

		var render_item = function(ul, d) {
			var html = "" + __(d.value) + "";
			if(d.description && d.value!==d.description) {
				html += '
' + __(d.description) + '';
			}
			return $('

')
				.data('item.autocomplete', d)
				.html('
' + html + '
')
				.appendTo(ul);
		};

		var open_recent = function() {
			if (!frappe.search.autocomplete_open) {
				$(this).autocomplete("search", "");
			}
		}

		$("#navbar-search")
			.on("focus", open_recent)
			.autocomplete(opts).data('ui-autocomplete')._renderItem = render_item;

		$("#sidebar-search")
			.on("focus", open_recent)
			.autocomplete(opts).data('ui-autocomplete')._renderItem = render_item;

		frappe.search.make_page_title_map();
		frappe.search.setup_recent();
	},
	add_help: function() {
		frappe.search.options.push({
			value: __("Help on Search"),
			onclick: function() {
				var txt = '
\

'+__("Make a new record")+'	'+
						__("new type of document")+'
\

'+__("List a document type")+'	'+
						__("document type..., e.g. customer")+'
\

'+__("Search in a document type")+'	'+
						__("text in document type")+'
\

'+__("Open a module or tool")+'	'+
						__("module name...")+'
\

'+__("Calculate")+'	'+
						__("e.g. (55 + 434) / 4 or =Math.sin(Math.PI/2)...")+'
\

'
				msgprint(txt, "Search Help");
			}
		});
	},
	make_page_title_map: function() {
		frappe.search.pages = {};
		$.each(frappe.boot.page_info, function(name, p) {
			frappe.search.pages[p.title] = p;
			p.name = name;
		});
	},
	setup_recent: function() {
		var recent = JSON.parse(frappe.boot.user.recent || "[]");
		frappe.search.recent = {};
		for (var i=0, l=recent.length; i < l; i++) {
			var d = recent[i];
			if (!frappe.search.recent[d[0]]) {
				frappe.search.recent[d[0]] = [];
			}
			frappe.search.recent[d[0]].push(d[1]);
		}
	},
	find: function(list, txt, process) {
		$.each(list, function(i, item) {
			_item = __(item).toLowerCase().replace(/-/g, " ");
			if(txt===_item || _item.indexOf(txt) !== -1) {
				var option = process(item);
				option.match = item;
				frappe.search.options.push(option);
			}
		});
	}
}

frappe.search.verbs = [
	// search in list if current
	function(txt) {
		var route = frappe.get_route();
		if(route[0]==="List" && txt.indexOf(" in") === -1) {
			// search in title field
			var meta = frappe.get_meta(frappe.container.page.doclistview.doctype);
			var search_field = meta.title_field || "name";
			var options = {};
			options[search_field] = ["like", "%" + txt + "%"];
			frappe.search.options.push({
				value: __('Find {0} in {1}', [""+txt+"", "" + route[1] + ""]),
				route_options: options,
				onclick: function() {
					frappe.container.page.doclistview.set_route_options();
				},
				match: txt
			});
		}
	},

	// recent
	function(txt) {
		var doctypes = frappe.utils.unique(keys(locals).concat(keys(frappe.search.recent)));
		for(var i in doctypes) {
			var doctype = doctypes[i];
			if(doctype[0]!==":" && !frappe.model.is_table(doctype)
				&& !in_list(frappe.boot.single_types, doctype)
				&& !in_list(["DocType", "DocField", "DocPerm", "Page", "Country",
					"Currency", "Page Role", "Print Format"], doctype)) {
				var values = frappe.utils.unique(keys(locals[doctype]).concat(frappe.search.recent[doctype] || []));
				var ret = frappe.search.find(values, txt, function(match) {
					return {
						value: __(doctype) + " " + match + "",
						route: ["Form", doctype, match]
					}
				});
			}
		}
	},

	// new doc
	function(txt) {
		var ret = false;
		if(txt.split(" ")[0]==="new") {
			frappe.search.find(frappe.boot.user.can_create, txt.substr(4), function(match) {
				return {
					value:__("New {0}", [""+match+""]),
					onclick: function() { new_doc(match); }
				}
			});
		}
	},

	// doctype list
	function(txt) {
		frappe.search.find(frappe.boot.user.can_read, txt, function(match) {
			if(in_list(frappe.boot.single_types, match)) {
				return {
					value: __("{0}", [""+__(match)+""]),
					route:["Form", match, match]
				}
			} else {
				return {
					value: __("{0} List", [""+__(match)+""]),
					route:["List", match]
				}
			}
		});
	},

	// pages
	function(txt) {
		frappe.search.find(keys(frappe.search.pages), txt, function(match) {
			return {
				value: __("Open {0}", [""+__(match)+""]),
				route: [frappe.search.pages[match].route || frappe.search.pages[match].name]
			}
		});
	},

	// modules
	function(txt) {
		frappe.search.find(keys(frappe.modules), txt, function(match) {
			ret = {
				value: __("Open {0}", [""+__(match)+""]),
			}
			if(frappe.modules[match].link) {
				ret.route = [frappe.modules[match].link];
			} else {
				ret.route = ["Module", match];
			}
			return ret;
		});
	},

	// in
	function(txt) {
		if(in_list(txt.split(" "), "in")) {
			parts = txt.split(" in ");
			frappe.search.find(frappe.boot.user.can_read, parts[1], function(match) {
				return {
					value: __('Find {0} in {1}', [""+__(parts[0])+"", ""+__(match)+""]),
					route_options: {"name": ["like", "%" + parts[0] + "%"]},
					route: ["List", match]
				}
			});
		}
	},

	// calculator
	function(txt) {
		var first = txt.substr(0,1);
		if(first==parseInt(first) || first==="(" || first==="=") {
			if(first==="=") {
				txt = txt.substr(1);
			}

			try {
				var val = eval(txt);
				var formatted_value = $.format('{0} = {1}', [txt, ""+val+""]);
				frappe.search.options.push({
					value: formatted_value,
					match: val,
					onclick: function(match) {
						msgprint(formatted_value, "Result");
					}
				});
			} catch(e) {
				// pass
			}

		};
	},
];
<|endoftext|>


<commit_before>define(["jquery", 'app/urlmanager', 'showutils', 'app/templates', 'app/auth'], function($, urlManager, showutils, templates, auth) {

    'use strict';

    var containerId = "#comments-container",
        comTemplate = null,
        comListTemplate = null,
        comEditTemplate = null,
        commentTextarea = null,
        comListContainer = null

    // Init comments interface
    function initComments() {
        comListTemplate = templates.get("comments-list", true)
        comEditTemplate = templates.get("comment-edit")
        comTemplate = templates.get("comments")
        $(containerId).html(comTemplate({}))
        commentTextarea = $("#comment-textarea"),
        comListContainer = $("#comments-list-container"),

        // Send comment
        $("#comment-send-button").click(function(e) {
            auth.validateMicroTokenTime(sendComment)
            return false
        })
    }

    // Add comment to a thread
    function sendComment() {
        var url = COMMENTS_API_URL + "/thread/" + urlManager.getParam('code') + "/add"
        var data = {
            'token': localStorage.microToken,
            'text': commentTextarea.val(),
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                commentTextarea.val("")
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data)
                alert(data.responseJSON.message)
            })
    }

    // Edit comment from a thread
    function editComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/edit"
        var data = {
            'token': localStorage.microToken,
            'text': $('#comment-edit-textarea-' + commentId).val(),
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'PUT',
        })
        .done(function(data) {
            commentTextarea.val("")
            drawComments(data)
        })
        .fail(function(data, error, errorName) {
            console.log(data)
            alert(data.responseJSON.message)
        })
    }

    // Delete comment from a thread
    function deleteComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/delete"
        var data = {
            'token': localStorage.microToken,
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'DELETE',
        })
            .done(function(data) {
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Like/dislike comment from a thread
    // vote == true: like; vote == false: dislike
    function voteComment(args) {
        var commentId = args.commentId
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/vote"
        var data = {
            'token': localStorage.microToken,
            'vote': args.vote,
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Delete comment from a thread
    function reportComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/report"
        // var data = {
        //     'token': localStorage.microToken,
        // }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            // data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                alert('Reportado!')
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Creates textarea for edition
    function editButtonClicked(event) {
        console.log(event)
        var commentId = event.currentTarget.dataset.commentId
        var commentBody = $('#comment-body-' + commentId)
        var oldText = commentBody.html()
        commentBody.html(
            comEditTemplate({
                'text': oldText,
                'id': commentId
            })
        )
        $('#comment-edit-send-button-' + commentId).click(function(event) {
            auth.validateMicroTokenTime(
                editComment,
                event.currentTarget.dataset.commentId
            )
            return false
        })
        var editButton = $('#comment-edit-button-' + commentId)
        var cancelButton = $('#comment-edit-cancel-button-' + commentId)
        // Cancel button function: go back text and switch buttons
        cancelButton.click(function(event) {
            commentBody.html(oldText)
            cancelButton.hide()
            editButton.show()
        })
        editButton.hide()
        cancelButton.show()
        return false
    }

    // Update comments list
    function updateComments(event, data) {
        if (!comTemplate) initComments()

        console.log("UPADETE-COMENTS", event, data, urlManager.getParam('code'))
        var code = typeof data !== 'undefined' ? data.value : urlManager.getParam('code')
        $.getJSON(
            COMMENTS_API_URL + '/thread/' + code
        )
        .done(function(data) {
            drawComments(data)
        })
    }

    // Draw comments
    function drawComments(data) {
        var current_user = auth.getUsername()
        // Sort comments by creation time
        data.comments = data.comments.sort(function(a, b){
            console.log(a.created > b.created)
            return a.created > b.created ? 1 : -1
        })
        // Mark comments by this user or not
        $.each(data.comments, function(index, comment) {
            if (comment.author == current_user) {
                comment.userIsAuthor = true
            } else {
                comment.userNotAuthor = true
            }
        })
        // Add HTML to page
        comListContainer.html(comListTemplate(data))
        // Activate edit buttons
        $('.edit-comment-button').click(editButtonClicked)
        // Activate delete buttons
        $('.delete-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                deleteComment,
                event.currentTarget.dataset.commentId
            )
            return false
        })
        // Activate report buttons
        $('.report-comment-button').click(function(event) {
            reportComment(event.currentTarget.dataset.commentId)
            return false
        })
        // Activate like buttons
        $('.like-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                voteComment,
                {
                    'commentId': event.currentTarget.dataset.commentId,
                    'vote': true
                }
            )
            return false
        })
        // Activate dislike buttons
        $('.dislike-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                voteComment,
                {
                    'commentId': event.currentTarget.dataset.commentId,
                    'vote': false
                }
            )
            return false
        })
    }

    showutils.showSubscribe("code.changed", containerId, true, updateComments)
})
<commit_msg>refac<commit_after>define(["jquery", 'app/urlmanager', 'showutils', 'app/templates', 'app/auth'], function($, urlManager, showutils, templates, auth) {

    'use strict';

    var containerId = "#comments-container",
        comTemplate = null,
        comListTemplate = null,
        comEditTemplate = null,
        commentTextarea = null,
        comListContainer = null

    // Init comments interface
    function initComments() {
        comListTemplate = templates.get("comments-list", true)
        comEditTemplate = templates.get("comment-edit")
        comTemplate = templates.get("comments")
        $(containerId).html(comTemplate({}))
        commentTextarea = $("#comment-textarea"),
        comListContainer = $("#comments-list-container"),

        // Send comment
        $("#comment-send-button").click(function(e) {
            auth.validateMicroTokenTime(sendComment)
            return false
        })
    }

    // Add comment to a thread
    function sendComment() {
        var url = COMMENTS_API_URL + "/thread/" + urlManager.getParam('code') + "/add"
        var data = {
            'token': localStorage.microToken,
            'text': commentTextarea.val(),
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                commentTextarea.val("")
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data)
                alert(data.responseJSON.message)
            })
    }

    // Edit comment from a thread
    function editComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/edit"
        var data = {
            'token': localStorage.microToken,
            'text': $('#comment-edit-textarea-' + commentId).val(),
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'PUT',
        })
        .done(function(data) {
            commentTextarea.val("")
            drawComments(data)
        })
        .fail(function(data, error, errorName) {
            console.log(data)
            alert(data.responseJSON.message)
        })
    }

    // Delete comment from a thread
    function deleteComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/delete"
        var data = {
            'token': localStorage.microToken,
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'DELETE',
        })
            .done(function(data) {
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Like/dislike comment from a thread
    // vote == true: like; vote == false: dislike
    function voteComment(args) {
        var commentId = args.commentId
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/vote"
        var data = {
            'token': localStorage.microToken,
            'vote': args.vote,
        }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                drawComments(data)
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Delete comment from a thread
    function reportComment(commentId) {
        var url = COMMENTS_API_URL + "/thread/" +
            urlManager.getParam('code') + "/" +
            commentId + "/report"
        // var data = {
        //     'token': localStorage.microToken,
        // }
        $.ajax({
            url        : url,
            dataType   : 'json',
            contentType: 'application/json; charset=UTF-8',
            // data       : JSON.stringify(data),
            type       : 'POST',
        })
            .done(function(data) {
                alert('Reportado!')
            })
            .fail(function(data, error, errorName) {
                console.log(data, error, errorName)
                alert(data.responseJSON.message)
            })
    }

    // Creates textarea for edition
    function editButtonClicked(event) {
        console.log(event)
        var commentId = event.currentTarget.dataset.commentId
        var commentBody = $('#comment-body-' + commentId)
        var oldText = commentBody.html()
        commentBody.html(
            comEditTemplate({
                'text': oldText,
                'id': commentId
            })
        )
        $('#comment-edit-send-button-' + commentId).click(function(event) {
            auth.validateMicroTokenTime(
                editComment,
                event.currentTarget.dataset.commentId
            )
            return false
        })
        var editButton = $('#comment-edit-button-' + commentId)
        var cancelButton = $('#comment-edit-cancel-button-' + commentId)
        // Cancel button function: go back text and switch buttons
        cancelButton.click(function(event) {
            commentBody.html(oldText)
            cancelButton.hide()
            editButton.show()
        })
        editButton.hide()
        cancelButton.show()
        return false
    }

    // Update comments list
    function updateComments(event, data) {
        if (!comTemplate) initComments()

        console.log("UPADETE-COMENTS", event, data, urlManager.getParam('code'))
        var code = typeof data !== 'undefined' ? data.value : urlManager.getParam('code')
        $.getJSON(
            COMMENTS_API_URL + '/thread/' + code
        )
        .done(function(data) {
            drawComments(data)
        })
    }

    // Draw comments
    function drawComments(data) {
        var current_user = auth.getUsername()
        // Sort comments by creation time
        data.comments = data.comments.sort(function(a, b){
            return a.created > b.created ? 1 : -1
        })
        // Mark comments by this user or not
        $.each(data.comments, function(index, comment) {
            if (comment.author == current_user) {
                comment.userIsAuthor = true
            } else {
                comment.userNotAuthor = true
            }
        })
        // Add HTML to page
        comListContainer.html(comListTemplate(data))
        // Activate edit buttons
        $('.edit-comment-button').click(editButtonClicked)
        // Activate delete buttons
        $('.delete-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                deleteComment,
                event.currentTarget.dataset.commentId
            )
            return false
        })
        // Activate report buttons
        $('.report-comment-button').click(function(event) {
            reportComment(event.currentTarget.dataset.commentId)
            return false
        })
        // Activate like buttons
        $('.like-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                voteComment,
                {
                    'commentId': event.currentTarget.dataset.commentId,
                    'vote': true
                }
            )
            return false
        })
        // Activate dislike buttons
        $('.dislike-comment-button').click(function(event) {
            auth.validateMicroTokenTime(
                voteComment,
                {
                    'commentId': event.currentTarget.dataset.commentId,
                    'vote': false
                }
            )
            return false
        })
    }

    showutils.showSubscribe("code.changed", containerId, true, updateComments)
})
<|endoftext|>


<commit_before>frappe.provide("frappe.ui");
frappe.provide("frappe.views");
frappe.provide("frappe.web_form_list");

export default class WebFormList {
	constructor(opts) {
		Object.assign(this, opts);
		frappe.web_form_list = this;
		this.wrapper = document.getElementById("datatable");
		this.refresh();
		this.make_actions();
		this.make_filters();
		$('.link-btn').remove()
	}

	refresh() {
		if (this.table) {
			Array.from(this.table.tBodies).forEach(tbody => tbody.remove());
			let check = document.getElementById('select-all')
			check.checked = false;
		}
		this.rows = [];
		this.page_length = 20;
		this.web_list_start = 0;

		frappe.run_serially([
			() => this.get_list_view_fields(),
			() => this.get_data(),
			() => this.make_table(),
		]);
	}

	make_filters() {
		this.filters = {}
		this.filter_input = []
		const filter_area = document.getElementById('list-filters');

		frappe.call('frappe.website.doctype.web_form.web_form.get_web_form_filters', {
			web_form_name: this.web_form_name
		}).then(response => {
			let fields = response.message;
			fields.forEach(field => {
				let col = document.createElement('div.col-sm-4')
				col.classList.add('col', 'col-sm-3')
				filter_area.appendChild(col)

				let input = frappe.ui.form.make_control({
					df: {
						fieldtype: field.fieldtype,
						fieldname: field.fieldname,
						options: field.options,
						only_select: true,
						label: __(field.label),
						onchange: (event) => {
							this.add_filter(field.fieldname, input.value, field.fieldtype)
						}
					},
					parent: col,
					render_input: 1,
				})
				this.filter_input.push(input)
			})
		})
	}

	add_filter(field, value, fieldtype) {
		if (!value && field in this.filters) {
			delete this.filters[field]
		}
		else {
			if (fieldtype === 'Data') value = ['like', value + '%']
			Object.assign(this.filters, Object.fromEntries([[field, value]]))
		}
		this.refresh();
	}

	get_list_view_fields() {
		return frappe
			.call({
				method:
					"frappe.website.doctype.web_form.web_form.get_in_list_view_fields",
				args: { doctype: this.doctype }
			})
			.then(response => (this.fields_list = response.message));
	}

	fetch_data() {
		return frappe.call({
			method: "frappe.www.list.get_list_data",
			args: {
				doctype: this.doctype,
				fields: this.fields_list.map(df => df.fieldname),
				limit_start: this.web_list_start,
				web_form_name: this.web_form_name,
				...this.filters
			}
		});
	}

	async get_data() {
		let response = await this.fetch_data();
		this.data = await response.message;
	}

	more() {
		this.web_list_start += this.page_length
		this.fetch_data().then((res) => {
			if (res.message.length === 0) {
				frappe.msgprint(__("No more items to display"))
			}
			this.append_rows(res.message)
		})

	}

	make_table() {
		this.columns = this.fields_list.map(df => {
			return {
				label: df.label,
				fieldname: df.fieldname,
				fieldtype: df.fieldtype
			};
		});

		if (! this.table) {
			this.table = document.createElement("table");
			this.table.classList.add("table");
			this.make_table_head();
		}

		this.append_rows(this.data);

		this.wrapper.appendChild(this.table);
	}

	make_table_head() {
		// Create Heading
		let thead = this.table.createTHead();
		thead.style.backgroundColor = "#f7fafc";
		thead.style.color = "#8d99a6";
		let row = thead.insertRow();

		let th = document.createElement("th");

		let checkbox = document.createElement("input");
		checkbox.type = "checkbox";
		checkbox.id = "select-all";
		checkbox.onclick = event =>
			this.toggle_select_all(event.target.checked);

		th.appendChild(checkbox);
		row.appendChild(th);

		add_heading(row, "Sr.");
		this.columns.forEach(col => {
			let th = document.createElement("th");
			let text = document.createTextNode(col.label);
			th.appendChild(text);
			row.appendChild(th);
		});

		function add_heading(row, label) {
			let th = document.createElement("th");
			th.innerText = label;
			row.appendChild(th);
		}
	}

	append_rows(row_data) {
		const tbody = this.table.childNodes[1] || this.table.createTBody();
		row_data.forEach((data_item) => {
			let row_element = tbody.insertRow();
			row_element.setAttribute("id", data_item.name);

			let row = new frappe.ui.WebFormListRow({
				row: row_element,
				doc: data_item,
				columns: this.columns,
				serial_number: this.rows.length + 1,
				events: {
					onEdit: () => this.open_form(data_item.name),
					onSelect: () => this.toggle_delete()
				}
			});

			this.rows.push(row);
		});
	}

	make_actions() {
		const actions = document.querySelector(".list-view-actions");
		const footer = document.querySelector(".list-view-footer");

		addButton(actions, "delete-rows", "danger", true, "Delete", () =>
			this.delete_rows()
		);

		addButton(
			actions,
			"new",
			"primary",
			false,
			"New",
			() => (window.location.href = window.location.pathname + "?new=1")
		);

		if (!(this.rows.length < this.page_length)) {
			addButton(footer, "more", "secondary", false, "More", () =>  this.more());
		}

		function addButton(wrapper, id, type, hidden, name, action) {
			const button = document.createElement("button");
			button.classList.add("btn", "btn-primary", "btn-sm", "ml-2");
			if (type == "secondary")
				button.classList.add(
					"btn",
					"btn-secondary",
					"btn-sm",
					"ml-2",
					"text-white"
				);
			if (type == "danger")
				button.classList.add(
					"btn",
					"btn-danger",
					"button-delete",
					"btn-sm",
					"ml-2"
				);

			button.id = id;
			button.innerText = name;
			button.hidden = hidden;

			button.onclick = action;
			wrapper.appendChild(button);
		}
	}

	toggle_select_all(checked) {
		this.rows.forEach(row => row.toggle_select(checked));
	}

	open_form(name) {
		window.location.href = window.location.pathname + "?name=" + name;
	}

	get_selected() {
		return this.rows.filter(row => row.is_selected());
	}

	toggle_delete() {
		if (!this.settings.allow_delete) return
		let btn = document.getElementById("delete-rows");
		btn.hidden = !this.get_selected().length;
	}

	delete_rows() {
		if (!this.settings.allow_delete) return
		frappe
			.call({
				type: "POST",
				method:
					"frappe.website.doctype.web_form.web_form.delete_multiple",
				args: {
					web_form_name: this.web_form_name,
					docnames: this.get_selected().map(row => row.doc.name)
				}
			})
			.then(() => {
				this.refresh()
				this.toggle_delete()
			});
	}
};

frappe.ui.WebFormListRow = class WebFormListRow {
	constructor({ row, doc, columns, serial_number, events, options }) {
		Object.assign(this, { row, doc, columns, serial_number, events });
		this.make_row();
	}

	make_row() {
		// Add Checkboxes
		let cell = this.row.insertCell();

		this.checkbox = document.createElement("input");
		this.checkbox.type = "checkbox";
		this.checkbox.onclick = event => {
			this.toggle_select(event.target.checked);
			event.stopImmediatePropagation();
		}

		cell.appendChild(this.checkbox);

		// Add Serial Number
		let serialNo = this.row.insertCell();
		serialNo.innerText = this.serial_number;

		this.columns.forEach(field => {
			let cell = this.row.insertCell();
			let formatter = frappe.form.get_formatter(field.fieldtype);
			cell.innerHTML = this.doc[field.fieldname] &&
				formatter(this.doc[field.fieldname], field, {only_value: 1}, this.doc) || "";
		});

		this.row.onclick = () => this.events.onEdit();
		this.row.style.cursor = "pointer";
	}

	toggle_select(checked) {
		this.checkbox.checked = checked;
		this.events.onSelect(checked);
	}

	is_selected() {
		return this.checkbox.checked;
	}
};<commit_msg>refactor: translated table headings<commit_after>frappe.provide("frappe.ui");
frappe.provide("frappe.views");
frappe.provide("frappe.web_form_list");

export default class WebFormList {
	constructor(opts) {
		Object.assign(this, opts);
		frappe.web_form_list = this;
		this.wrapper = document.getElementById("datatable");
		this.refresh();
		this.make_actions();
		this.make_filters();
		$('.link-btn').remove()
	}

	refresh() {
		if (this.table) {
			Array.from(this.table.tBodies).forEach(tbody => tbody.remove());
			let check = document.getElementById('select-all')
			check.checked = false;
		}
		this.rows = [];
		this.page_length = 20;
		this.web_list_start = 0;

		frappe.run_serially([
			() => this.get_list_view_fields(),
			() => this.get_data(),
			() => this.make_table(),
		]);
	}

	make_filters() {
		this.filters = {}
		this.filter_input = []
		const filter_area = document.getElementById('list-filters');

		frappe.call('frappe.website.doctype.web_form.web_form.get_web_form_filters', {
			web_form_name: this.web_form_name
		}).then(response => {
			let fields = response.message;
			fields.forEach(field => {
				let col = document.createElement('div.col-sm-4')
				col.classList.add('col', 'col-sm-3')
				filter_area.appendChild(col)

				let input = frappe.ui.form.make_control({
					df: {
						fieldtype: field.fieldtype,
						fieldname: field.fieldname,
						options: field.options,
						only_select: true,
						label: __(field.label),
						onchange: (event) => {
							this.add_filter(field.fieldname, input.value, field.fieldtype)
						}
					},
					parent: col,
					render_input: 1,
				})
				this.filter_input.push(input)
			})
		})
	}

	add_filter(field, value, fieldtype) {
		if (!value && field in this.filters) {
			delete this.filters[field]
		}
		else {
			if (fieldtype === 'Data') value = ['like', value + '%']
			Object.assign(this.filters, Object.fromEntries([[field, value]]))
		}
		this.refresh();
	}

	get_list_view_fields() {
		return frappe
			.call({
				method:
					"frappe.website.doctype.web_form.web_form.get_in_list_view_fields",
				args: { doctype: this.doctype }
			})
			.then(response => (this.fields_list = response.message));
	}

	fetch_data() {
		return frappe.call({
			method: "frappe.www.list.get_list_data",
			args: {
				doctype: this.doctype,
				fields: this.fields_list.map(df => df.fieldname),
				limit_start: this.web_list_start,
				web_form_name: this.web_form_name,
				...this.filters
			}
		});
	}

	async get_data() {
		let response = await this.fetch_data();
		this.data = await response.message;
	}

	more() {
		this.web_list_start += this.page_length
		this.fetch_data().then((res) => {
			if (res.message.length === 0) {
				frappe.msgprint(__("No more items to display"))
			}
			this.append_rows(res.message)
		})

	}

	make_table() {
		this.columns = this.fields_list.map(df => {
			return {
				label: df.label,
				fieldname: df.fieldname,
				fieldtype: df.fieldtype
			};
		});

		if (! this.table) {
			this.table = document.createElement("table");
			this.table.classList.add("table");
			this.make_table_head();
		}

		this.append_rows(this.data);

		this.wrapper.appendChild(this.table);
	}

	make_table_head() {
		// Create Heading
		let thead = this.table.createTHead();
		thead.style.backgroundColor = "#f7fafc";
		thead.style.color = "#8d99a6";
		let row = thead.insertRow();

		let th = document.createElement("th");

		let checkbox = document.createElement("input");
		checkbox.type = "checkbox";
		checkbox.id = "select-all";
		checkbox.onclick = event =>
			this.toggle_select_all(event.target.checked);

		th.appendChild(checkbox);
		row.appendChild(th);

		add_heading(row, "Sr.");
		this.columns.forEach(col => {
			let th = document.createElement("th");
			let text = document.createTextNode(__(col.label));
			th.appendChild(text);
			row.appendChild(th);
		});

		function add_heading(row, label) {
			let th = document.createElement("th");
			th.innerText = label;
			row.appendChild(th);
		}
	}

	append_rows(row_data) {
		const tbody = this.table.childNodes[1] || this.table.createTBody();
		row_data.forEach((data_item) => {
			let row_element = tbody.insertRow();
			row_element.setAttribute("id", data_item.name);

			let row = new frappe.ui.WebFormListRow({
				row: row_element,
				doc: data_item,
				columns: this.columns,
				serial_number: this.rows.length + 1,
				events: {
					onEdit: () => this.open_form(data_item.name),
					onSelect: () => this.toggle_delete()
				}
			});

			this.rows.push(row);
		});
	}

	make_actions() {
		const actions = document.querySelector(".list-view-actions");
		const footer = document.querySelector(".list-view-footer");

		addButton(actions, "delete-rows", "danger", true, "Delete", () =>
			this.delete_rows()
		);

		addButton(
			actions,
			"new",
			"primary",
			false,
			"New",
			() => (window.location.href = window.location.pathname + "?new=1")
		);

		if (!(this.rows.length < this.page_length)) {
			addButton(footer, "more", "secondary", false, "More", () =>  this.more());
		}

		function addButton(wrapper, id, type, hidden, name, action) {
			const button = document.createElement("button");
			button.classList.add("btn", "btn-primary", "btn-sm", "ml-2");
			if (type == "secondary")
				button.classList.add(
					"btn",
					"btn-secondary",
					"btn-sm",
					"ml-2",
					"text-white"
				);
			if (type == "danger")
				button.classList.add(
					"btn",
					"btn-danger",
					"button-delete",
					"btn-sm",
					"ml-2"
				);

			button.id = id;
			button.innerText = name;
			button.hidden = hidden;

			button.onclick = action;
			wrapper.appendChild(button);
		}
	}

	toggle_select_all(checked) {
		this.rows.forEach(row => row.toggle_select(checked));
	}

	open_form(name) {
		window.location.href = window.location.pathname + "?name=" + name;
	}

	get_selected() {
		return this.rows.filter(row => row.is_selected());
	}

	toggle_delete() {
		if (!this.settings.allow_delete) return
		let btn = document.getElementById("delete-rows");
		btn.hidden = !this.get_selected().length;
	}

	delete_rows() {
		if (!this.settings.allow_delete) return
		frappe
			.call({
				type: "POST",
				method:
					"frappe.website.doctype.web_form.web_form.delete_multiple",
				args: {
					web_form_name: this.web_form_name,
					docnames: this.get_selected().map(row => row.doc.name)
				}
			})
			.then(() => {
				this.refresh()
				this.toggle_delete()
			});
	}
};

frappe.ui.WebFormListRow = class WebFormListRow {
	constructor({ row, doc, columns, serial_number, events, options }) {
		Object.assign(this, { row, doc, columns, serial_number, events });
		this.make_row();
	}

	make_row() {
		// Add Checkboxes
		let cell = this.row.insertCell();

		this.checkbox = document.createElement("input");
		this.checkbox.type = "checkbox";
		this.checkbox.onclick = event => {
			this.toggle_select(event.target.checked);
			event.stopImmediatePropagation();
		}

		cell.appendChild(this.checkbox);

		// Add Serial Number
		let serialNo = this.row.insertCell();
		serialNo.innerText = this.serial_number;

		this.columns.forEach(field => {
			let cell = this.row.insertCell();
			let formatter = frappe.form.get_formatter(field.fieldtype);
			cell.innerHTML = this.doc[field.fieldname] &&
				formatter(this.doc[field.fieldname], field, {only_value: 1}, this.doc) || "";
		});

		this.row.onclick = () => this.events.onEdit();
		this.row.style.cursor = "pointer";
	}

	toggle_select(checked) {
		this.checkbox.checked = checked;
		this.events.onSelect(checked);
	}

	is_selected() {
		return this.checkbox.checked;
	}
};<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Grid from 'material-ui/Grid'
import Typography from 'material-ui/Typography'
import { injectStripe } from 'react-stripe-elements'

import CardSection from './card-section'
import UserSection from './user-section'
import Button from 'material-ui/Button'

class CheckoutForm extends Component {
  constructor (props) {
    super(props)

    this.handleSubmit = this.handleSubmit.bind(this)
    this.onChange = this.onChange.bind(this)

    this.state = {
      email: null,
      fullname: null,
      authenticated: false,
      userId: null,
      error: {
        fullname: false,
        email: false,
        payment: false,
        message: 'loading'
      },
      paymentRequested: false
    }
  }

  handleSubmit (ev) {
    ev.preventDefault()

    this.setState({ paymentRequested: true })

    // Within the context of `Elements`, this call to createToken knows which Element to
    // tokenize, since there's only one in this group.
    if (!this.state.fullname) {
      this.setState({ error: { fullname: true } })
      return
    }
    else {
      this.setState({ error: { fullname: false } })
    }

    if (!this.state.email) {
      this.setState({ error: { email: true } })
    }
    else {
      this.setState({ error: { email: false } })
    }
    if (!this.props.stripe) {
      return
    }
    this.props.stripe
      .createToken({ name: this.state.fullname })
      .then(({ token }) => {
        if (token) {
          try {
            this.props.onPayment({
              id: this.props.task,
              Orders: [
                {
                  source_id: token.id,
                  currency: 'usd',
                  provider: 'stripe',
                  amount: this.props.itemPrice,
                  email: this.state.email,
                  userId: this.state.userId
                }
              ]
            })
            this.props.onClose()
          }
          catch (e) {
            this.props.addNotification(
              'Erro ao processar o pagamento do cartão de crédito'
            )
            this.setState({
              paymentRequested: false
            })
          }
        }
        else {
          this.props.addNotification('Erro no pagamento')
          this.setState({
            paymentRequested: false
          })
        }
      })
      .catch(e => {
        // eslint-disable-next-line no-console
        console.log('error to create token')
        // eslint-disable-next-line no-console
        console.log(e)
        this.props.addNotification('Erro no pagamento')
        this.setState({
          paymentRequested: false
        })
      })

    // However, this line of code will do the same thing:
    // this.props.stripe.createToken({type: 'card', name: 'Jenny Rosen'});
  }

  onChange (ev) {
    ev.preventDefault()
    let formData = {}
    formData[ev.target.name] = ev.target.value
    this.setState(formData)
  }

  componentDidMount () {
    const { user } = this.props

    if (user && user.id) {
      this.setState({
        authenticated: true,
        fullname: user.name,
        email: user.email,
        userId: user.id
      })
    }
  }

  render () {
    const logged = this.state.authenticated
    const { user } = this.props

    return (
      <form
        onSubmit={ this.handleSubmit }
        onChange={ this.onChange }
        style={ { marginTop: 20 } }
      >
        <Grid container spacing={ 24 }>
          <Grid item xs={ 12 } style={ { marginBottom: 20 } }>
            { logged ? (

                { user && user.name ? (

                    <Typography variant='caption'>
                      Você está logado como
                    </Typography>
                    <Typography variant='subheading'>
                      { `${this.state.fullname} (${this.state.email})` }
                    </Typography>

                ) : (
                  <UserSection error={ this.state.error } name={ this.state.fullname } email={ this.state.email } />
                ) }

            ) : (
              <UserSection error={ this.state.error } />
            ) }
          </Grid>
          <Grid item xs={ 12 }>
            <CardSection { ...this.props } />
          </Grid>
          <Grid item xs={ 12 }>

              <Button color='primary' onClick={ this.props.onClose }>
                Cancelar
              </Button>
              <Button
                type='submit'
                variant='raised'
                color='secondary'
                disabled={ this.state.paymentRequested }
              >
                { `Pagar $ ${this.props.itemPrice}` }
              </Button>

          </Grid>
        </Grid>
      </form>
    )
  }
}

CheckoutForm.propTypes = {
  stripe: PropTypes.object,
  onPayment: PropTypes.func,
  task: PropTypes.any,
  onClose: PropTypes.func,
  addNotification: PropTypes.func,
  itemPrice: PropTypes.any,
  user: PropTypes.object
}

export const CheckoutFormPure = CheckoutForm
export default injectStripe(CheckoutForm)
<commit_msg>fixing wrong disable field when type wrong card number<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Grid from 'material-ui/Grid'
import Typography from 'material-ui/Typography'
import { injectStripe } from 'react-stripe-elements'

import CardSection from './card-section'
import UserSection from './user-section'
import Button from 'material-ui/Button'

class CheckoutForm extends Component {
  constructor (props) {
    super(props)

    this.handleSubmit = this.handleSubmit.bind(this)
    this.onChange = this.onChange.bind(this)

    this.state = {
      email: null,
      fullname: null,
      authenticated: false,
      userId: null,
      error: {
        fullname: false,
        email: false,
        payment: false,
        message: 'loading'
      },
      paymentRequested: false
    }
  }

  handleSubmit (ev) {
    ev.preventDefault()

    this.setState({ paymentRequested: true })

    // Within the context of `Elements`, this call to createToken knows which Element to
    // tokenize, since there's only one in this group.
    if (!this.state.fullname) {
      this.setState({ error: { fullname: true } })
      return
    }
    else {
      this.setState({ error: { fullname: false } })
    }

    if (!this.state.email) {
      this.setState({ error: { email: true } })
    }
    else {
      this.setState({ error: { email: false } })
    }
    if (!this.props.stripe) {
      return
    }
    this.props.stripe
      .createToken({ name: this.state.fullname })
      .then(({ token }) => {
        if (token) {
          try {
            this.props.onPayment({
              id: this.props.task,
              Orders: [
                {
                  source_id: token.id,
                  currency: 'usd',
                  provider: 'stripe',
                  amount: this.props.itemPrice,
                  email: this.state.email,
                  userId: this.state.userId
                }
              ]
            })
            this.props.onClose()
          }
          catch (e) {
            this.props.addNotification(
              'Erro ao processar o pagamento do cartão de crédito'
            )
            this.setState({
              paymentRequested: false
            })
          }
        }
        else {
          this.props.addNotification('Erro no pagamento')
          this.setState({
            paymentRequested: false
          })
        }
      })
      .catch(e => {
        // eslint-disable-next-line no-console
        console.log('error to create token')
        // eslint-disable-next-line no-console
        console.log(e)
        this.props.addNotification('Erro no pagamento')
        this.setState({
          paymentRequested: false
        })
      })

    // However, this line of code will do the same thing:
    // this.props.stripe.createToken({type: 'card', name: 'Jenny Rosen'});
  }

  onChange (ev) {
    ev.preventDefault()
    let formData = {}
    formData[ev.target.name] = ev.target.value
    this.setState(formData)
    this.setState({ paymentRequested: false })
  }

  componentDidMount () {
    const { user } = this.props

    if (user && user.id) {
      this.setState({
        authenticated: true,
        fullname: user.name,
        email: user.email,
        userId: user.id
      })
    }
  }

  render () {
    const logged = this.state.authenticated
    const { user } = this.props

    return (
      <form
        onSubmit={ this.handleSubmit }
        onChange={ this.onChange }
        style={ { marginTop: 20 } }
      >
        <Grid container spacing={ 24 }>
          <Grid item xs={ 12 } style={ { marginBottom: 20 } }>
            { logged ? (

                { user && user.name ? (

                    <Typography variant='caption'>
                      Você está logado como
                    </Typography>
                    <Typography variant='subheading'>
                      { `${this.state.fullname} (${this.state.email})` }
                    </Typography>

                ) : (
                  <UserSection error={ this.state.error } name={ this.state.fullname } email={ this.state.email } />
                ) }

            ) : (
              <UserSection error={ this.state.error } />
            ) }
          </Grid>
          <Grid item xs={ 12 }>
            <CardSection { ...this.props } />
          </Grid>
          <Grid item xs={ 12 }>

              <Button color='primary' onClick={ this.props.onClose }>
                Cancelar
              </Button>
              <Button
                type='submit'
                variant='raised'
                color='secondary'
                disabled={ this.state.paymentRequested }
              >
                { `Pagar $ ${this.props.itemPrice}` }
              </Button>

          </Grid>
        </Grid>
      </form>
    )
  }
}

CheckoutForm.propTypes = {
  stripe: PropTypes.object,
  onPayment: PropTypes.func,
  task: PropTypes.any,
  onClose: PropTypes.func,
  addNotification: PropTypes.func,
  itemPrice: PropTypes.any,
  user: PropTypes.object
}

export const CheckoutFormPure = CheckoutForm
export default injectStripe(CheckoutForm)
<|endoftext|>


<commit_before>/// <reference types="cypress" />

context('Core', () => {
  beforeEach(() => {
    cy.swiperPage();
  });
  describe('centeredSlides & slidesPerView', () => {
    beforeEach(() => {
      cy.initSwiper({
        centeredSlides: true,
        slidesPerView: 3,
        speed: 0,
        spaceBetween: 10,
        navigation: true,
      });
    });
    it('should have slide with active class', () => {
      cy.getSlide(0).expectToBeActiveSlide().and('be.visible');
    });

    it('should position slides center', () => {
      cy.getActiveSlide().should(($el) => {
        expect($el[0].getBoundingClientRect().x).to.be.greaterThan(100);
      });
    });

    it('should not has slide with prev class', () => {
      cy.getSlides().should('not.have.class', 'swiper-slide-prev');
    });

    it('should have slide with next class', () => {
      cy.getSlide(1).should('have.class', 'swiper-slide-next').and('be.visible');
    });
    describe('visible slides', () => {
      it('should have 2 visible slides', () => {
        cy.getSlides().filter(':visible').its('length').should('be.eq', 2);
      });
      it('should have 3 visible slides after navigation', () => {
        cy.swipeLeft();
        cy.getSlides().filter(':visible').its('length').should('be.eq', 3);
      });
    });

    it('spaceBetween', () => {
      cy.getSlides()
        .should('have.attr', 'style')
        .and('match', /margin-right:\s+10px/);
    });
  });

  describe('methods', () => {
    beforeEach(() => {
      cy.initSwiper().as('swiper');
    });
    it('should slide next', function slideNext() {
      this.swiper.slideNext();
      cy.getSlideContains('Slide 2').expectToBeActiveSlide();
    });
    it('should slide prev', function slidePrev() {
      this.swiper.slideNext();
      this.swiper.slidePrev();
      cy.getSlideContains('Slide 1').expectToBeActiveSlide();
    });
    it('should slide to slide 3', function slideTo3() {
      this.swiper.slideTo(2);
      cy.getSlideContains('Slide 3').expectToBeActiveSlide();
    });
    // it('should slide to first slide when slideTo called with number bigger then slides amount', function () {
    //   this.swiper.slideTo(14);
    //   cy.getSlideContains('Slide 1').expectToBeActiveSlide();
    // });
    it('Add slide at index', function slideTo() {
      this.swiper.addSlide(1, '
Add slide
');
      cy.getSlide(1).should('contain', 'Add slide');
      this.swiper.addSlide(4, '
Add slide 4
');
      cy.getSlide(4).should('contain', 'Add slide 4');
    });

    // it('Add multiple slides at index', function () {
    //   this.swiper.addSlide(0, [
    //     '
Add slide 0
',
    //     '
Add slide 1
',
    //     '
Add slide 2
',
    //   ]);
    //   // cy.getSlide(2).should('contain', 'Add slide 0');
    //   // cy.getSlide(1).should('contain', 'Add slide 1');
    //   cy.getSlide(0).should('contain', 'Add slide 2');
    // });

    it('Add slide to the end', function slideToEnd() {
      this.swiper.appendSlide('
Add slide at the end
');
      cy.getSlide(10).should('contain', 'Add slide at the end');
      this.swiper.appendSlide([
        '
END 1
',
        '
END 2
',
      ]);
      cy.getSlide(11).should('contain', 'END 1');
      cy.getSlide(12).should('contain', 'END 2');
    });
  });

  it('initialSlide', () => {
    cy.initSwiper({
      initialSlide: 2,
    });
    cy.getSlideContains('Slide 3').expectToBeActiveSlide();
    cy.reinitSwiper({
      initialSlide: 4,
    });
    cy.getSlideContains('Slide 5').expectToBeActiveSlide();
    cy.reinitSwiper({
      initialSlide: 0,
    });
    cy.getSlideContains('Slide 1').expectToBeActiveSlide();
  });

  it('containerModifierClass', () => {
    cy.initSwiper({
      containerModifierClass: 'unique-test-',
    });
    cy.get('.unique-test-horizontal').should('exist');
    cy.get('.swiper-container-horizontal').should('not.exist');
  });

  it('slideActiveClass', () => {
    cy.initSwiper({
      slideActiveClass: 'unique-test-active',
    });
    cy.get('.unique-test-active').should('exist');
    cy.get('.swiper-slide-active').should('not.exist');
  });

  it('slideBlankClass & loopFillGroupWithBlank', () => {
    cy.initSwiper({
      slideBlankClass: 'unique-test-invisible-blank',
      loop: true,
      slidesPerGroup: 3,
      loopFillGroupWithBlank: true,
    });
    cy.get('.unique-test-invisible-blank').should('exist');
    cy.get('.swiper-slide-invisible-blank').should('not.exist');
  });

  it('slideDuplicateActiveClass', () => {
    cy.initSwiper({
      loop: true,
      slideDuplicateActiveClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-active').should('not.exist');
  });

  it('slideDuplicateNextClass', () => {
    cy.initSwiper({
      loop: true,
      slidesPerView: 2,
      slideDuplicateNextClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-next').should('not.exist');
  });

  it('slideDuplicatePrevClass', () => {
    cy.initSwiper({
      loop: true,
      slidesPerView: 2,
      slideDuplicatePrevClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-prev').should('not.exist');
  });

  it('slideNextClass', () => {
    cy.initSwiper({
      slidesPerView: 2,
      slideNextClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-next').should('not.exist');
  });

  it('slidePrevClass', () => {
    cy.initSwiper({
      slidesPerView: 2,
      initialSlide: 2,
      slidePrevClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-prev').should('not.exist');
  });

  it('slideToClickedSlide', () => {
    cy.initSwiper({
      slideToClickedSlide: true,
      slidesPerView: 5,
    });
    cy.getSlide(3).click().expectToBeActiveSlide();
    cy.getSlide(4).click().expectToBeActiveSlide();
  });
  it('grabCursor', () => {
    cy.initSwiper({
      grabCursor: true,
    });
    cy.getSliderContainer()
      .should('have.attr', 'style')
      .and('match', /cursor:\s+grab/);
  });

  it('direction horizontal', () => {
    cy.initSwiper(); // check default
    cy.get('.swiper-container-horizontal').should('exist');
    cy.get('.swiper-container-vertical').should('not.exist');
    cy.reinitSwiper({
      direction: 'horizontal',
    });
    cy.get('.swiper-container-horizontal').should('exist');
    cy.get('.swiper-container-vertical').should('not.exist');
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().x).to.be.greaterThan(100);
    });
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().y).to.be.not.greaterThan(100);
    });
  });

  it('direction vertical', () => {
    cy.initSwiper({
      direction: 'vertical',
    });
    cy.get('.swiper-container-vertical').should('exist');
    cy.get('.swiper-container-horizontal').should('not.exist');
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().y).to.be.greaterThan(100);
    });
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().x).to.be.not.greaterThan(100);
    });
  });

  it('loop', () => {
    cy.initSwiper({
      loop: true,
    });
    cy.getSlide(0).should('contain', 'Slide 10');
    cy.swipeRight();
    cy.getSlideContains('Slide 10').expectToBeActiveSlide();
  });

  it('Swipe left & right', () => {
    cy.initSwiper({
      speed: 0,
    });
    cy.swipeLeft();
    cy.getSlide(1).expectToBeActiveSlide();
    cy.swipeLeft();
    cy.swipeLeft();
    cy.getSlide(3).expectToBeActiveSlide();
    cy.swipeRight();
    cy.getSlide(2).expectToBeActiveSlide();
    cy.swipeRight();
    cy.swipeRight();
    cy.getSlide(0).expectToBeActiveSlide();
  });
});
<commit_msg>tests(core): slideVisibleClass<commit_after>/// <reference types="cypress" />

context('Core', () => {
  beforeEach(() => {
    cy.swiperPage();
  });
  describe('centeredSlides & slidesPerView', () => {
    beforeEach(() => {
      cy.initSwiper({
        centeredSlides: true,
        slidesPerView: 3,
        speed: 0,
        spaceBetween: 10,
        navigation: true,
      });
    });
    it('should have slide with active class', () => {
      cy.getSlide(0).expectToBeActiveSlide().and('be.visible');
    });

    it('should position slides center', () => {
      cy.getActiveSlide().should(($el) => {
        expect($el[0].getBoundingClientRect().x).to.be.greaterThan(100);
      });
    });

    it('should not has slide with prev class', () => {
      cy.getSlides().should('not.have.class', 'swiper-slide-prev');
    });

    it('should have slide with next class', () => {
      cy.getSlide(1).should('have.class', 'swiper-slide-next').and('be.visible');
    });
    describe('visible slides', () => {
      it('should have 2 visible slides', () => {
        cy.getSlides().filter(':visible').its('length').should('be.eq', 2);
      });
      it('should have 3 visible slides after navigation', () => {
        cy.swipeLeft();
        cy.getSlides().filter(':visible').its('length').should('be.eq', 3);
      });
    });

    it('spaceBetween', () => {
      cy.getSlides()
        .should('have.attr', 'style')
        .and('match', /margin-right:\s+10px/);
    });
  });

  describe('methods', () => {
    beforeEach(() => {
      cy.initSwiper().as('swiper');
    });
    it('should slide next', function slideNext() {
      this.swiper.slideNext();
      cy.getSlideContains('Slide 2').expectToBeActiveSlide();
    });
    it('should slide prev', function slidePrev() {
      this.swiper.slideNext();
      this.swiper.slidePrev();
      cy.getSlideContains('Slide 1').expectToBeActiveSlide();
    });
    it('should slide to slide 3', function slideTo3() {
      this.swiper.slideTo(2);
      cy.getSlideContains('Slide 3').expectToBeActiveSlide();
    });
    // it('should slide to first slide when slideTo called with number bigger then slides amount', function () {
    //   this.swiper.slideTo(14);
    //   cy.getSlideContains('Slide 1').expectToBeActiveSlide();
    // });
    it('Add slide at index', function slideTo() {
      this.swiper.addSlide(1, '
Add slide
');
      cy.getSlide(1).should('contain', 'Add slide');
      this.swiper.addSlide(4, '
Add slide 4
');
      cy.getSlide(4).should('contain', 'Add slide 4');
    });

    // it('Add multiple slides at index', function () {
    //   this.swiper.addSlide(0, [
    //     '
Add slide 0
',
    //     '
Add slide 1
',
    //     '
Add slide 2
',
    //   ]);
    //   // cy.getSlide(2).should('contain', 'Add slide 0');
    //   // cy.getSlide(1).should('contain', 'Add slide 1');
    //   cy.getSlide(0).should('contain', 'Add slide 2');
    // });

    it('Add slide to the end', function slideToEnd() {
      this.swiper.appendSlide('
Add slide at the end
');
      cy.getSlide(10).should('contain', 'Add slide at the end');
      this.swiper.appendSlide([
        '
END 1
',
        '
END 2
',
      ]);
      cy.getSlide(11).should('contain', 'END 1');
      cy.getSlide(12).should('contain', 'END 2');
    });
  });

  it('initialSlide', () => {
    cy.initSwiper({
      initialSlide: 2,
    });
    cy.getSlideContains('Slide 3').expectToBeActiveSlide();
    cy.reinitSwiper({
      initialSlide: 4,
    });
    cy.getSlideContains('Slide 5').expectToBeActiveSlide();
    cy.reinitSwiper({
      initialSlide: 0,
    });
    cy.getSlideContains('Slide 1').expectToBeActiveSlide();
  });

  it('containerModifierClass', () => {
    cy.initSwiper({
      containerModifierClass: 'unique-test-',
    });
    cy.get('.unique-test-horizontal').should('exist');
    cy.get('.swiper-container-horizontal').should('not.exist');
  });

  it('slideActiveClass', () => {
    cy.initSwiper({
      slideActiveClass: 'unique-test-active',
    });
    cy.get('.unique-test-active').should('exist');
    cy.get('.swiper-slide-active').should('not.exist');
  });

  it('slideBlankClass & loopFillGroupWithBlank', () => {
    cy.initSwiper({
      slideBlankClass: 'unique-test-invisible-blank',
      loop: true,
      slidesPerGroup: 3,
      loopFillGroupWithBlank: true,
    });
    cy.get('.unique-test-invisible-blank').should('exist');
    cy.get('.swiper-slide-invisible-blank').should('not.exist');
  });

  it('slideDuplicateActiveClass', () => {
    cy.initSwiper({
      loop: true,
      slideDuplicateActiveClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-active').should('not.exist');
  });

  it('slideDuplicateNextClass', () => {
    cy.initSwiper({
      loop: true,
      slidesPerView: 2,
      slideDuplicateNextClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-next').should('not.exist');
  });

  it('slideDuplicatePrevClass', () => {
    cy.initSwiper({
      loop: true,
      slidesPerView: 2,
      slideDuplicatePrevClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-duplicate-prev').should('not.exist');
  });

  it('slideNextClass', () => {
    cy.initSwiper({
      slidesPerView: 2,
      slideNextClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-next').should('not.exist');
  });

  it('slidePrevClass', () => {
    cy.initSwiper({
      slidesPerView: 2,
      initialSlide: 2,
      slidePrevClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-prev').should('not.exist');
  });

  it('slideVisibleClass', () => {
    cy.initSwiper({
      slidesPerView: 2,
      watchSlidesVisibility: true,
      slideVisibleClass: 'uniqueTestClass',
    });
    cy.get('.uniqueTestClass').should('exist');
    cy.get('.swiper-slide-visible').should('not.exist');
  });

  it('slideToClickedSlide', () => {
    cy.initSwiper({
      slideToClickedSlide: true,
      slidesPerView: 5,
    });
    cy.getSlide(3).click().expectToBeActiveSlide();
    cy.getSlide(4).click().expectToBeActiveSlide();
  });
  it('grabCursor', () => {
    cy.initSwiper({
      grabCursor: true,
    });
    cy.getSliderContainer()
      .should('have.attr', 'style')
      .and('match', /cursor:\s+grab/);
  });

  it('direction horizontal', () => {
    cy.initSwiper(); // check default
    cy.get('.swiper-container-horizontal').should('exist');
    cy.get('.swiper-container-vertical').should('not.exist');
    cy.reinitSwiper({
      direction: 'horizontal',
    });
    cy.get('.swiper-container-horizontal').should('exist');
    cy.get('.swiper-container-vertical').should('not.exist');
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().x).to.be.greaterThan(100);
    });
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().y).to.be.not.greaterThan(100);
    });
  });

  it('direction vertical', () => {
    cy.initSwiper({
      direction: 'vertical',
    });
    cy.get('.swiper-container-vertical').should('exist');
    cy.get('.swiper-container-horizontal').should('not.exist');
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().y).to.be.greaterThan(100);
    });
    cy.getSlide(2).should(($el) => {
      expect($el[0].getBoundingClientRect().x).to.be.not.greaterThan(100);
    });
  });

  it('loop', () => {
    cy.initSwiper({
      loop: true,
    });
    cy.getSlide(0).should('contain', 'Slide 10');
    cy.swipeRight();
    cy.getSlideContains('Slide 10').expectToBeActiveSlide();
  });

  it('Swipe left & right', () => {
    cy.initSwiper({
      speed: 0,
    });
    cy.swipeLeft();
    cy.getSlide(1).expectToBeActiveSlide();
    cy.swipeLeft();
    cy.swipeLeft();
    cy.getSlide(3).expectToBeActiveSlide();
    cy.swipeRight();
    cy.getSlide(2).expectToBeActiveSlide();
    cy.swipeRight();
    cy.swipeRight();
    cy.getSlide(0).expectToBeActiveSlide();
  });
});
<|endoftext|>


<commit_before>const {knex} = require('../util/database').connect();

function createOrUpdateMood(opts) {
  const upsertMoodSql = `
    WITH upsert AS
      (UPDATE
        wappu_mood
      SET
        rating = ?,
        description = ?,
        updated_at = CURRENT_TIMESTAMP
      WHERE
        user_id = ? AND created_at_coarse = CURRENT_DATE
      RETURNING
        *
      )
    INSERT INTO wappu_mood (user_id, rating, description)
    SELECT ?, ?, ? WHERE NOT EXISTS (SELECT * FROM upsert)
  `;

  let params = [
    opts.rating, opts.description, opts.client.id,
    opts.client.id, opts.rating, opts.description
  ];

  return knex.transaction(trx =>
    trx.raw(upsertMoodSql, params)
    .then(result => undefined)
    .catch(err => {
      err.message = 'Error updating database';
      err.status = 500;
      throw err;
    })
  );
}

function getMood(opts) {
  const getMoodSql = `
    SELECT
      ${ _getSelectSql(opts) }
    FROM wappu_mood
    LEFT JOIN teams ON teams.id = wappu_mood.user_id
    ${ _getWhereSql(opts) }
    GROUP BY
      wappu_mood.created_at_fine,
      wappu_mood.description,
      wappu_mood.rating
  `;

  return knex.transaction(trx =>
    trx.raw(getMoodSql)
    .then(result => result.rows)
    .catch(err => {
      err.message = 'Error reading database';
      err.status = 500;
      throw err;
    })
  );
}

function _getSelectSql(opts) {
  const publicSql = `
    DATE_TRUNC('day', wappu_mood.created_at_fine) AS date,
    ROUND(AVG(wappu_mood.rating)::numeric, 4) AS avg_rating,
    COUNT(wappu_mood.rating) AS votes_cast
  `;

  const personalSql = `
    DATE_TRUNC('day', created_at_fine) AS date,
    wappu_mood.rating,
    wappu_mood.description
  `;

  return opts.personal ? personalSql : publicSql;

}

function _getWhereSql(opts) {
  // Personal is the strictest, hence no other filter is required;
  if (opts.personal) {
    return knex.raw(
      ` WHERE wappu_mood.user_id = ? `,
      [opts.client.id]
    ).toString();
  }

  let filters = [];
  let params = [];

  if (opts.cityId) {
    filters.push(`teams.city_id = ?`);
    params.push(opts.cityId);
  }

  if (opts.cityName) {
    filters.push(`
      teams.city_id IN (
        SELECT cities.id
        FROM cities
        WHERE cities.name = ?
      )
    `);
    params.push(opts.cityName);
  }

  if (opts.teamId) {
    filters.push(`teams.id = ?`);
    params.push(opts.teamId);
  }

  if (params.teamName) {
    filters.push(`teams.name = ?`);
    params.push(opts.teamName);
  }

  let sqlString = filters.length > 0 ? ` WHERE ${ filters.join(' AND ')} ` : ''

  return knex.raw(sqlString, params).toString();
}

export {
  createOrUpdateMood,
  getMood,
};
<commit_msg>Response body fields from snake_case to camelCase<commit_after>const {knex} = require('../util/database').connect();
import {deepChangeKeyCase} from '../util';

function createOrUpdateMood(opts) {
  const upsertMoodSql = `
    WITH upsert AS
      (UPDATE
        wappu_mood
      SET
        rating = ?,
        description = ?,
        updated_at = CURRENT_TIMESTAMP
      WHERE
        user_id = ? AND created_at_coarse = CURRENT_DATE
      RETURNING
        *
      )
    INSERT INTO wappu_mood (user_id, rating, description)
    SELECT ?, ?, ? WHERE NOT EXISTS (SELECT * FROM upsert)
  `;

  let params = [
    opts.rating, opts.description, opts.client.id,
    opts.client.id, opts.rating, opts.description
  ];

  return knex.transaction(trx =>
    trx.raw(upsertMoodSql, params)
      .then(result => undefined)
      .catch(err => {
        err.message = 'Error updating database';
        err.status = 500;
        throw err;
      })
  );
}

function getMood(opts) {
  const getMoodSql = `
    SELECT
      ${ _getSelectSql(opts) }
    FROM wappu_mood
    LEFT JOIN teams ON teams.id = wappu_mood.user_id
    ${ _getWhereSql(opts) }
    GROUP BY
      wappu_mood.created_at_fine,
      wappu_mood.description,
      wappu_mood.rating
  `;

  return knex.transaction(trx =>
    trx.raw(getMoodSql)
      .then(result => _rowsToMoodObjects(result.rows))
      .catch(err => {
        err.message = 'Error reading database';
        err.status = 500;
        throw err;
      })
  );
}

function _getSelectSql(opts) {
  const publicSql = `
    DATE_TRUNC('day', wappu_mood.created_at_fine) AS date,
    ROUND(AVG(wappu_mood.rating)::numeric, 4) AS avg_rating,
    COUNT(wappu_mood.rating) AS votes_cast
  `;

  const personalSql = `
    DATE_TRUNC('day', created_at_fine) AS date,
    wappu_mood.rating,
    wappu_mood.description
  `;

  return opts.personal ? personalSql : publicSql;

}

function _getWhereSql(opts) {
  // Personal is the strictest, hence no other filter is required;
  if (opts.personal) {
    return knex.raw(
      ` WHERE wappu_mood.user_id = ? `,
      [opts.client.id]
    ).toString();
  }

  let filters = [];
  let params = [];

  if (opts.cityId) {
    filters.push(`teams.city_id = ?`);
    params.push(opts.cityId);
  }

  if (opts.cityName) {
    filters.push(`
      teams.city_id IN (
        SELECT cities.id
        FROM cities
        WHERE cities.name = ?
      )
    `);
    params.push(opts.cityName);
  }

  if (opts.teamId) {
    filters.push(`teams.id = ?`);
    params.push(opts.teamId);
  }

  if (params.teamName) {
    filters.push(`teams.name = ?`);
    params.push(opts.teamName);
  }

  let sqlString = filters.length > 0 ? ` WHERE ${ filters.join(' AND ')} ` : ''

  return knex.raw(sqlString, params).toString();
}

function _rowsToMoodObjects(rows) {
  return rows.map(row => deepChangeKeyCase(row, 'camelCase'));
}

export {
  createOrUpdateMood,
  getMood,
};
<|endoftext|>


<commit_before>(function(d3, _, helpers, extensions) {
  var mixin = helpers.mixin;
  var property = helpers.property;
  var di = helpers.di;

  /**
    Labels
    Chart with labels positioned at (x,y) points

    Properties:
    - {String} [position = top] top, right, bottom, left, or a|b (a for positive values or 0, b for negative)
    - {Number} [offset = 10] px distance offset from data point
    - {String|Function} format String to be used in d3.format(...) or format function
  */
  d3.chart('Chart').extend('Labels', mixin(extensions.XY, {
    initialize: function() {
      this.seriesLayer('Labels', this.base.append('g').classed('chart-labels', true), {
        dataBind: function(data) {
          var chart = this.chart();
          return this.selectAll('text')
            .data(data, chart.keyValue);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('text')
            .classed('chart-label', true)
            .attr('alignment-baseline', chart.labelAlignment)
            .attr('style', chart.itemStyle);
        },
        events: {
          'enter': function() {
            var chart = this.chart();
            this
              .attr('x', chart.labelX)
              .attr('y', chart.y0)
              .attr('text-anchor', chart.labelAnchor)
              .text(0);
          },
          'merge:transition': function() {
            var chart = this.chart();
            this
              .attr('y', chart.labelY)
              .text(chart.labelValue);
          }
        }
      });
    },

    transform: function(data) {
      // TODO reduce data (by mechanism similar to ticks)
      return data;
    },

    display: property('display', {defaultValue: true}),
    format: property('format', {
      type: 'Function',
      set: function(value) {
        if (_.isString(value)) {
          return {override: d3.format(value)};
        }
      }
    }),

    position: property('position', {defaultValue: 'top'}),
    offset: property('offset', {defaultValue: 14}),

    labelX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) + chart.calculatedOffset.call(this, d, i).x;
    }),
    labelY: di(function(chart, d, i) {
      return chart.y.call(this, d, i) + chart.calculatedOffset.call(this, d, i).y;
    }),
    labelValue: di(function(chart, d, i) {
      if (!chart.display()) return;

      var value = chart.yValue.call(this, d, i);
      return chart.format() ? chart.format()(value) : value;
    }),

    calculatedOffset: di(function(chart, d, i) {
      var offset = chart.offset();

      var byPosition = {
        top: {x: 0, y: -offset},
        right: {x: offset, y: 0},
        bottom: {x: 0, y: offset},
        left: {x: -offset, y: 0}
      };

      return byPosition[chart.calculatedPosition.call(this, d, i)];
    }),
    labelAnchor: di(function(chart, d, i) {
      if (chart.calculatedPosition.call(this, d, i) == 'right')
        return 'start';
      else if (chart.calculatedPosition.call(this, d, i) == 'left')
        return 'end';
      else
        return 'middle';
    }),
    labelAlignment: di(function(chart, d, i) {
      // Set alignment-baseline so that font size does not play into calculations
      // http://www.w3.org/TR/SVG/text.html#BaselineAlignmentProperties
      var byPosition = {
        top: 'after-edge',
        right: 'middle',
        bottom: 'before-edge',
        left: 'middle'
      };

      return byPosition[chart.calculatedPosition.call(this, d, i)];
    }),

    calculatedPosition: di(function(chart, d, i) {
      var position = chart.position();
      var parts = position.split('|');

      if (parts.length > 1) {
        var value = parts[0] == 'top' || parts[0] == 'bottom' ? chart.yValue.call(this, d, i) : chart.xValue.call(this, d, i);
        return value >= 0 ? parts[0] : parts[1];
      }
      else {
        return parts[0];
      }
    }),

    itemStyle: di(function(chart, d, i) {
      // For labels, only pull in label styles
      // - data.labels.style
      // - series.labels.style
      var series = chart.dataSeries.call(this, d, i) || {};
      var styles = _.defaults({}, d.labels && d.labels.style, series.labels && series.labels.style, chart.options().style);

      return helpers.style(styles) || null;
    }),
  }));

  /**
    LabelValues
    Chart with labels for centered values
  */
  d3.chart('Labels').extend('LabelsValues', mixin(extensions.Values, {
    labelX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) + chart.calculatedOffset.call(this, d, i).x;
    })
  }));

  /**
    ChartWithLabels
    Chart with labels attached
  */
  d3.chart('Chart').extend('ChartWithLabels', {
    attachLabels: function() {
      var Labels = helpers.resolveChart('', 'Labels', this.isValues ? 'Values' : 'XY');
      this.labels = new Labels(this.base, this.labelOptions());

      // Pull x/y scale from parent chart
      this.labels.xScale = property('xScale', {
        get: function() {
          return this._xScale();
        },
        context: this
      });
      this.labels.yScale = property('yScale', {
        get: function() {
          return this._yScale();
        },
        context: this
      });

      this.attach('Labels', this.labels);
    },

    options: property('options', {
      set: function(options) {
        this.setFromOptions(options);

        if (this.labels)
          this.labels.options(this.labelOptions(), {silent: true});
      }
    }),

    labelOptions: property('labelOptions', {
      get: function() {
        var options = this.options().labels;

        // If no options or options is false, display = false
        // If options is true, display = true
        // Otherwise use options given
        if (!options)
          options = {display: false};
        else if (options === true)
          options = {display: true};
        else
          options = _.clone(options);

        // Pull options from parent chart
        options = _.defaults(options, {
          displayAdjacent: this.displayAdjacent ? this.displayAdjacent() : false
        });

        return options;
      }
    })
  });

  /**
    Bars
    Bar graph with centered key,value data and adjacent display for series
  */
  d3.chart('ChartWithLabels').extend('Bars', mixin(extensions.XY, extensions.Values, {
    initialize: function() {
      this.seriesLayer('Bars', this.base.append('g').classed('chart-bars', true), {
        dataBind: function(data) {
          var chart = this.chart();

          return this.selectAll('rect')
            .data(data, chart.keyValue);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('rect')
            .classed('chart-bar', true)
            .attr('style', chart.itemStyle);
        },
        events: {
          'enter': function() {
            var chart = this.chart();
            this
                .attr('x', chart.barX)
                .attr('y', chart.y0)
                .attr('width', chart.itemWidth)
                .attr('height', 0);
          },
          'merge:transition': function() {
            var chart = this.chart();
            this
                .attr('y', chart.barY)
                .attr('height', chart.barHeight);
          }
        }
      });

      this.attachLabels();
    },

    barHeight: di(function(chart, d, i) {
      var height = Math.abs(chart.y0.call(this, d, i) - chart.y.call(this, d, i));
      return height > 0 ? height - chart.barOffset() : 0;
    }),
    barX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) - chart.itemWidth.call(this, d, i) / 2;
    }),
    barY: di(function(chart, d, i) {
      var y = chart.y.call(this, d, i);
      var y0 = chart.y0();

      return y < y0 ? y : y0 + chart.barOffset();
    }),
    displayAdjacent: property('displayAdjacent', {defaultValue: true}),

    barOffset: function barOffset() {
      if (!this.__axis)
        this.__axis = d3.select(chart.base[0][0].parentNode).select('[data-id="axis.x"] .domain');

      var axisThickness = this.__axis[0][0] && parseInt(this.__axis.style('stroke-width')) || 0;
      return axisThickness / 2;
    }
  }));

  /**
    Line
    (x,y) line graph
  */
  d3.chart('ChartWithLabels').extend('Line', mixin(extensions.XY, {
    initialize: function() {
      this.seriesLayer('Lines', this.base.append('g').classed('chart-lines', true), {
        dataBind: function(data) {
          var chart = this.chart();

          // Add lines based on underlying series data
          chart.lines(_.map(chart.data(), function(series) {
            return chart.createLine(series);
          }));

          // Rather than use provided series data
          return this.selectAll('path')
            .data(function(d, i) {
              return [chart.data()[i]];
            }, chart.seriesKey);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('path')
            .classed('chart-line', true)
            .attr('style', chart.itemStyle);
        },
        events: {
          'merge:transition': function() {
            var chart = this.chart();
            var lines = chart.lines();

            this
              .attr('d', function(d, i) {
                return lines[chart.seriesIndex.call(this, d, i)](chart.seriesValues.call(this, d, i));
              })
              .attr('style', chart.itemStyle);
          }
        }
      });

      this.attachLabels();
    },
    lines: property('lines', {defaultValue: []}),

    createLine: function(series) {
      var line = d3.svg.line()
        .x(this.x)
        .y(this.y);

      var interpolate = series.interpolate || this.options().interpolate;
      if (interpolate)
        line.interpolate(interpolate);

      return line;
    },
    insertSwatch: function() {
      return this.append('line')
        .attr('x1', 0).attr('y1', 10)
        .attr('x2', 20).attr('y2', 10)
        .attr('class', 'chart-line');
    }
  }));

  /**
    LineValues
    Line graph for centered key,value data
  */
  d3.chart('Line').extend('LineValues', extensions.Values);

})(d3, _, d3.chart.helpers, d3.chart.extensions);
<commit_msg>Fix bar offset bug<commit_after>(function(d3, _, helpers, extensions) {
  var mixin = helpers.mixin;
  var property = helpers.property;
  var di = helpers.di;

  /**
    Labels
    Chart with labels positioned at (x,y) points

    Properties:
    - {String} [position = top] top, right, bottom, left, or a|b (a for positive values or 0, b for negative)
    - {Number} [offset = 10] px distance offset from data point
    - {String|Function} format String to be used in d3.format(...) or format function
  */
  d3.chart('Chart').extend('Labels', mixin(extensions.XY, {
    initialize: function() {
      this.seriesLayer('Labels', this.base.append('g').classed('chart-labels', true), {
        dataBind: function(data) {
          var chart = this.chart();
          return this.selectAll('text')
            .data(data, chart.keyValue);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('text')
            .classed('chart-label', true)
            .attr('alignment-baseline', chart.labelAlignment)
            .attr('style', chart.itemStyle);
        },
        events: {
          'enter': function() {
            var chart = this.chart();
            this
              .attr('x', chart.labelX)
              .attr('y', chart.y0)
              .attr('text-anchor', chart.labelAnchor)
              .text(0);
          },
          'merge:transition': function() {
            var chart = this.chart();
            this
              .attr('y', chart.labelY)
              .text(chart.labelValue);
          }
        }
      });
    },

    transform: function(data) {
      // TODO reduce data (by mechanism similar to ticks)
      return data;
    },

    display: property('display', {defaultValue: true}),
    format: property('format', {
      type: 'Function',
      set: function(value) {
        if (_.isString(value)) {
          return {override: d3.format(value)};
        }
      }
    }),

    position: property('position', {defaultValue: 'top'}),
    offset: property('offset', {defaultValue: 14}),

    labelX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) + chart.calculatedOffset.call(this, d, i).x;
    }),
    labelY: di(function(chart, d, i) {
      return chart.y.call(this, d, i) + chart.calculatedOffset.call(this, d, i).y;
    }),
    labelValue: di(function(chart, d, i) {
      if (!chart.display()) return;

      var value = chart.yValue.call(this, d, i);
      return chart.format() ? chart.format()(value) : value;
    }),

    calculatedOffset: di(function(chart, d, i) {
      var offset = chart.offset();

      var byPosition = {
        top: {x: 0, y: -offset},
        right: {x: offset, y: 0},
        bottom: {x: 0, y: offset},
        left: {x: -offset, y: 0}
      };

      return byPosition[chart.calculatedPosition.call(this, d, i)];
    }),
    labelAnchor: di(function(chart, d, i) {
      if (chart.calculatedPosition.call(this, d, i) == 'right')
        return 'start';
      else if (chart.calculatedPosition.call(this, d, i) == 'left')
        return 'end';
      else
        return 'middle';
    }),
    labelAlignment: di(function(chart, d, i) {
      // Set alignment-baseline so that font size does not play into calculations
      // http://www.w3.org/TR/SVG/text.html#BaselineAlignmentProperties
      var byPosition = {
        top: 'after-edge',
        right: 'middle',
        bottom: 'before-edge',
        left: 'middle'
      };

      return byPosition[chart.calculatedPosition.call(this, d, i)];
    }),

    calculatedPosition: di(function(chart, d, i) {
      var position = chart.position();
      var parts = position.split('|');

      if (parts.length > 1) {
        var value = parts[0] == 'top' || parts[0] == 'bottom' ? chart.yValue.call(this, d, i) : chart.xValue.call(this, d, i);
        return value >= 0 ? parts[0] : parts[1];
      }
      else {
        return parts[0];
      }
    }),

    itemStyle: di(function(chart, d, i) {
      // For labels, only pull in label styles
      // - data.labels.style
      // - series.labels.style
      var series = chart.dataSeries.call(this, d, i) || {};
      var styles = _.defaults({}, d.labels && d.labels.style, series.labels && series.labels.style, chart.options().style);

      return helpers.style(styles) || null;
    }),
  }));

  /**
    LabelValues
    Chart with labels for centered values
  */
  d3.chart('Labels').extend('LabelsValues', mixin(extensions.Values, {
    labelX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) + chart.calculatedOffset.call(this, d, i).x;
    })
  }));

  /**
    ChartWithLabels
    Chart with labels attached
  */
  d3.chart('Chart').extend('ChartWithLabels', {
    attachLabels: function() {
      var Labels = helpers.resolveChart('', 'Labels', this.isValues ? 'Values' : 'XY');
      this.labels = new Labels(this.base, this.labelOptions());

      // Pull x/y scale from parent chart
      this.labels.xScale = property('xScale', {
        get: function() {
          return this._xScale();
        },
        context: this
      });
      this.labels.yScale = property('yScale', {
        get: function() {
          return this._yScale();
        },
        context: this
      });

      this.attach('Labels', this.labels);
    },

    options: property('options', {
      set: function(options) {
        this.setFromOptions(options);

        if (this.labels)
          this.labels.options(this.labelOptions(), {silent: true});
      }
    }),

    labelOptions: property('labelOptions', {
      get: function() {
        var options = this.options().labels;

        // If no options or options is false, display = false
        // If options is true, display = true
        // Otherwise use options given
        if (!options)
          options = {display: false};
        else if (options === true)
          options = {display: true};
        else
          options = _.clone(options);

        // Pull options from parent chart
        options = _.defaults(options, {
          displayAdjacent: this.displayAdjacent ? this.displayAdjacent() : false
        });

        return options;
      }
    })
  });

  /**
    Bars
    Bar graph with centered key,value data and adjacent display for series
  */
  d3.chart('ChartWithLabels').extend('Bars', mixin(extensions.XY, extensions.Values, {
    initialize: function() {
      this.seriesLayer('Bars', this.base.append('g').classed('chart-bars', true), {
        dataBind: function(data) {
          var chart = this.chart();

          return this.selectAll('rect')
            .data(data, chart.keyValue);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('rect')
            .classed('chart-bar', true)
            .attr('style', chart.itemStyle);
        },
        events: {
          'enter': function() {
            var chart = this.chart();
            this
                .attr('x', chart.barX)
                .attr('y', chart.y0)
                .attr('width', chart.itemWidth)
                .attr('height', 0);
          },
          'merge:transition': function() {
            var chart = this.chart();
            this
                .attr('y', chart.barY)
                .attr('height', chart.barHeight);
          }
        }
      });

      this.attachLabels();
    },

    barHeight: di(function(chart, d, i) {
      var height = Math.abs(chart.y0.call(this, d, i) - chart.y.call(this, d, i));
      return height > 0 ? height - chart.barOffset() : 0;
    }),
    barX: di(function(chart, d, i) {
      return chart.x.call(this, d, i) - chart.itemWidth.call(this, d, i) / 2;
    }),
    barY: di(function(chart, d, i) {
      var y = chart.y.call(this, d, i);
      var y0 = chart.y0();

      return y < y0 ? y : y0 + chart.barOffset();
    }),
    displayAdjacent: property('displayAdjacent', {defaultValue: true}),

    barOffset: function barOffset() {
      if (!this.__axis)
        this.__axis = d3.select(this.base[0][0].parentNode).select('[data-id="axis.x"] .domain');

      var axisThickness = this.__axis[0][0] && parseInt(this.__axis.style('stroke-width')) || 0;
      return axisThickness / 2;
    }
  }));

  /**
    Line
    (x,y) line graph
  */
  d3.chart('ChartWithLabels').extend('Line', mixin(extensions.XY, {
    initialize: function() {
      this.seriesLayer('Lines', this.base.append('g').classed('chart-lines', true), {
        dataBind: function(data) {
          var chart = this.chart();

          // Add lines based on underlying series data
          chart.lines(_.map(chart.data(), function(series) {
            return chart.createLine(series);
          }));

          // Rather than use provided series data
          return this.selectAll('path')
            .data(function(d, i) {
              return [chart.data()[i]];
            }, chart.seriesKey);
        },
        insert: function() {
          var chart = this.chart();

          return this.append('path')
            .classed('chart-line', true)
            .attr('style', chart.itemStyle);
        },
        events: {
          'merge:transition': function() {
            var chart = this.chart();
            var lines = chart.lines();

            this
              .attr('d', function(d, i) {
                return lines[chart.seriesIndex.call(this, d, i)](chart.seriesValues.call(this, d, i));
              })
              .attr('style', chart.itemStyle);
          }
        }
      });

      this.attachLabels();
    },
    lines: property('lines', {defaultValue: []}),

    createLine: function(series) {
      var line = d3.svg.line()
        .x(this.x)
        .y(this.y);

      var interpolate = series.interpolate || this.options().interpolate;
      if (interpolate)
        line.interpolate(interpolate);

      return line;
    },
    insertSwatch: function() {
      return this.append('line')
        .attr('x1', 0).attr('y1', 10)
        .attr('x2', 20).attr('y2', 10)
        .attr('class', 'chart-line');
    }
  }));

  /**
    LineValues
    Line graph for centered key,value data
  */
  d3.chart('Line').extend('LineValues', extensions.Values);

})(d3, _, d3.chart.helpers, d3.chart.extensions);
<|endoftext|>