<commit_before>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Store Bot Client Info #3",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Bot Client Control",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const info = ['Total Amount of Channels', 'Total Amount of Emojis', 'Bot\'s Previous Pings'];
	return `${info[parseInt(data.info)]}`;
},

//---------------------------------------------------------------------
// Action Storage Function
//
// Stores the relevant variable info for the editor.
//---------------------------------------------------------------------

variableStorage: function(data, varType) {
	const type = parseInt(data.storage);
	if(type !== varType) return;
	const info = parseInt(data.info);
	let dataType = 'Unknown Type';
	switch(info) {
		case 0:
			dataType = "Number";
			break;
		case 1:
			dataType = "Number";
			break;
		case 1:
			dataType = "Number";
			break;
	}
	return ([data.varName2, dataType]);
},

//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["info", "storage", "varName2"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

			Mod Info:

			Created by EGGSY!

	Source Info:

	<select id="info" class="round">
		<option value="0">Total Amount of Channels</option>
		<option value="1">Total Amount of Emojis</option>
		<option value="2">Bot's Previous Pings</option>
	</select>

		Store In:

		<select id="storage" class="round">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName2" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.messageChange(document.getElementById('message'), 'varNameContainer')
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const data = cache.actions[cache.index];
	const botClient = this.getDBM().Bot.bot;
	const info = parseInt(data.info);
	if(!botClient) {
		this.callNextAction(cache);
		return;
	}
	switch(info) {
		case 0:
			result = botClient.channels.size;
			break;
		case 1:
			result = botClient.emojis.size;
			break;
		case 2:
			result = botClient.pings;
			break;
		default:
		break;
	}
	if(result !== undefined) {
		const storage = parseInt(data.storage);
		const varName2 = this.evalMessage(data.varName2, cache);
		this.storeValue(result, storage, varName2, cache);
	}
	this.callNextAction(cache);
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module, thanks to Lasse btw!
<commit_msg>Added "Uptime in Days" and fixed some stuff.<commit_after>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Store Bot Client Info #3",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Bot Client Control",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const info = ['Total Amount of Channels', 'Total Amount of Emojis', 'Bot\'s Previous Pings', 'Uptime in Days', 'Uptime in Days (Rounded)'];
	return `${info[parseInt(data.info)]}`;
},

//---------------------------------------------------------------------
// Action Storage Function
//
// Stores the relevant variable info for the editor.
//---------------------------------------------------------------------

variableStorage: function(data, varType) {
	const type = parseInt(data.storage);
	if(type !== varType) return;
	const info = parseInt(data.info);
	let dataType = 'Unknown Type';
	switch(info) {
		case 0:
			dataType = "Number";
			break;
		case 1:
			dataType = "Number";
			break;
		case 2:
			dataType = "Number";
			break;
		case 3:
			dataType = "Time";
			break;
		case 4:
			dataType = "Time";
			break;
	}
	return ([data.varName2, dataType]);
},

//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["info", "storage", "varName2"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

			Mod Info:

			Created by EGGSY!

	Source Info:

	<select id="info" class="round">
		<option value="0">Total Amount of Channels</option>
		<option value="1">Total Amount of Emojis</option>
		<option value="2">Bot's Previous Pings</option>
		<option value="3">Uptime in Days</option>
		<option value="4">Uptime in Days (Rounded)</option>
	</select>

		Store In:

		<select id="storage" class="round">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName2" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.messageChange(document.getElementById('message'), 'varNameContainer')
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const data = cache.actions[cache.index];
	const botClient = this.getDBM().Bot.bot;
	const info = parseInt(data.info);
	const msToDay = (1000*60*60*24);
	if(!botClient) {
		this.callNextAction(cache);
		return;
	}
	switch(info) {
		case 0:
			result = botClient.channels.size;
			break;
		case 1:
			result = botClient.emojis.size;
			break;
		case 2:
			result = botClient.pings;
			break;
		case 3:
			result = botClient.uptime/msToDay;
			break;
		case 4:
			result = Math.floor(botClient.uptime/msToDay);
			break;
		default:
		break;
	}
	if(result !== undefined) {
		const storage = parseInt(data.storage);
		const varName2 = this.evalMessage(data.varName2, cache);
		this.storeValue(result, storage, varName2, cache);
	}
	this.callNextAction(cache);
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module, thanks to Lasse btw!
<|endoftext|>


<commit_before>openerp.base_kanban = function (openerp) {
QWeb.add_template('/base_kanban/static/src/xml/base_kanban.xml');
openerp.base.views.add('kanban', 'openerp.base_kanban.KanbanView');
openerp.base_kanban.KanbanView = openerp.base.View.extend({

    init: function(parent, element_id, dataset, view_id) {
        this._super(parent, element_id);
        this.view_manager = parent;
        this.dataset = dataset;
        this.model = this.dataset.model;
        this.view_id = view_id;
        this.group_by_field = false;
        this.source_index = {};
        this.all_display_data = false;
        this.groups = [];
    },

    start: function() {
        this.rpc("/base_kanban/kanbanview/load",
        {"model": this.model, "view_id": this.view_id}, this.on_loaded);
    },
    on_loaded: function(data) {
        var self = this;
        this.template_xml = '';
        this.columns = data.all_fields;
        _.each(data.fields_view.arch.children, function(child) {
            if (child.tag == "template"){
                self.template_xml = openerp.base.json_node_to_xml(child, true)
            }
        });
        if(this.template_xml){
            self.dataset.read_slice([], 0, false, function (records) {
                self.all_display_data = [{'records': records, 'value':false, 'header': false, 'ids': self.dataset.ids}];
                self.on_show_data(self.all_display_data);
	        });
	    }
    },

    on_show_data: function(datas) {
        var self = this;
        this.all_records = [];
        var new_qweb = new QWeb2.Engine();
		self.$element.html(QWeb.render("KanbanBiew", {"datas" :datas}));
        this.on_reload_kanban();
		this.$element.find(".oe_column").sortable({
		    connectWith: ".oe_column",
		    start: function(event, ui) {
                self.source_index['index'] = ui.item.index();
                self.source_index['column'] = ui.item.parent().attr('id');
            },
		    stop: self.on_recieve_record,
		});
		this.$element.find(".record").addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
		    .find(".record-header")
		        .addClass("ui-widget-header ui-corner-all")
		        .prepend( "")
		        .end()
		    .find( ".record-content" );

		this.$element.find(".record-header .ui-icon").click(function() {
		    $(this).toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
		    $(this).parents(".record:first").find(".record-content").toggle();
		});
		this.$element.find('.record .ui-icon-closethick').click(this.on_close_action);
		this.$element.find(".oe_column").disableSelection();
    },

    on_button_click: function(button_attrs, record_id){
        var self = this;
        if(this.groups.length){
            _.each(this.groups, function (group) {
                self.dataset.context = group.context;
                self.dataset.domain = group.domain;
                self.dataset.read_slice(false, false, false, function(records) {
                    var index = parseInt(_.indexOf(self.dataset.ids, record_id));
                    if(index >= 0) {
                        self.on_confirm_click(button_attrs, index, record_id);
                        return false;
                    }
                });
            });
        } else{
            var index = parseInt(_.indexOf(self.dataset.ids, record_id));
            if(index >= 0) {
                self.on_confirm_click(button_attrs, index, record_id)
            }
        }
    },

    on_confirm_click: function(button_attrs, index, record_id){
        if(button_attrs.type == 'edit') {
            this.select_record(index);
        } else{
            this.on_execute_button_click(button_attrs, record_id)
        }
    },

    select_record:function (index) {
        if(this.view_manager) {
            this.dataset.index = index;
            this.view_manager.on_mode_switch('form');
        }
    },

    do_delete: function (id) {
        var self = this;
        return $.when(this.dataset.unlink([id])).then(function () {
            self.drop_records(id);
        });
    },

    drop_records: function (id) {
        var self = this;
        _.each(self.all_display_data, function(data, index) {
            _.each(data.records, function(record, index_row) {
                if(parseInt(record.id) == id) {
                    self.all_display_data[index]['records'].splice(index_row, 1)
                    return false;
                }
            });
        });
        self.$element.find("#main_" + id).remove()
    },

    on_execute_button_click: function(button_attrs, record_id) {
        var self = this;
        this.execute_action(
            button_attrs, this.dataset, this.session.action_manager,
            record_id, function () {
                _.each(self.all_display_data, function(data, index) {
                    self.dataset.read_ids( data.ids, [], function(records){
                        self.all_display_data[index].records = records;
                        self.on_reload_kanban();
                    });
                });
            }
        );
    },

    on_close_action: function(e) {
        var record_id = $(e.currentTarget).parents('.record:first').attr("id")
        if(record_id) {
            record_id = parseInt(record_id.split("_")[1])
            if(record_id) {
                this.do_delete(record_id);
            }
        }
    },

    on_recieve_record: function(event, ui) {
        var self = this;
        var from = ui.item.index();
        this.flag = false;
        var to = ui.item.prev().index() || 0;
        if(!ui.item.attr("id")){
            return false;
        }
        if(self.columns.sequence && self.source_index.index && self.source_index.index != from) {
	        var child_record = ui.item.parent().children();
	        var data, sequence = 1, index = to;
	        child_record.splice(0, to);
	        if(to >= 0 && child_record) {
	            var record_id = child_record.attr('id').split("_");
	            if(record_id.length >= 2) {
		            _.each(self.all_records, function(record){
		                if(parseInt(record_id[1]) == record.id && record.sequence) {
		                    sequence = record.sequence;
		                    return false;
		                }
		            });
	            }
	        }
	        _.each(child_record, function (child) {
	            var child_id = parseInt($(child).attr("id").split("_")[1]);
	            if(child_id) {
	                _.each(self.all_display_data, function(data, index) {
	                    _.each(data.records, function(record, index_row) {
	                        if(parseInt(record.id) == child_id) {
	                            self.all_display_data[index]['records'][index_row]['sequence'] = sequence;
	                            return false;
	                        }
	                    });
	                });
	                self.dataset.write(child_id, {sequence: sequence});
	                sequence++;
	                self.flag = true;
	            }
	        });
        }
        if(self.group_by_field && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) {
            var value = ui.item.closest("td").attr("id")
            if(value) {
                var data_val = {};
                var wirte_id = parseInt(ui.item.attr("id").split("_")[1]);
                value = value.split("_")[1];
                if(value == 'false') {
                    value = false;
                }
                var update_record = false;
                _.each(self.all_display_data, function(data, index) {
                    _.each(data.records, function(record, index_row) {
                        if(parseInt(record.id) == wirte_id) {
                            self.all_display_data[index]['records'][index_row][self.group_by_field] = value;
                            update_record = self.all_display_data[index]['records'].splice(index_row,1)
                            return false;
                        }
                    });
                });
                _.each(self.all_display_data, function(data, index) {
                    if (data.value == value || (data.value == 'false' && value == false)) {
                        self.all_display_data[index]['records'].push(update_record[0]);
                    }
                });
                data_val[self.group_by_field] = value;
                self.dataset.write(wirte_id, data_val);
                self.flag = true;
            }
        }
        if(self.flag) {
            self.on_reload_kanban();
        }
        this.source_index = {};
    },

    on_reload_kanban: function(){
        var self = this;
        var new_qweb = new QWeb2.Engine();
        this.all_records = []
        new_qweb.add_template('<templates><t t-name="custom_template">' + this.template_xml + '</t></templates>')
        _.each(self.all_display_data, function(data, index) {
            if(data.records.length > 0){
                _.each(data.records, function(record) {
                    self.$element.find("#data_" + record.id).children().remove()
                    self.$element.find("#data_" + record.id).append(new_qweb.render('custom_template', record));
                    self.all_records.push(record);
	            });
            }
            else{
                self.$element.find("#column_" + data.value).remove();
                self.all_display_data.splice(index, 1);
            }
        });
        this.$element.find( ".oe_table_column " ).css("width", 99 / self.all_display_data.length +"%");
        this.$element.find('button').click(function(){
            var record_id = $(this).closest(".record").attr("id");
            if(record_id) {
                record_id = parseInt(record_id.split("_")[1])
                if(record_id) {
                    if($(this).data("type") == "delete") {
                        self.do_delete(record_id);
                    }
                    else{
                        var button_attrs = $(this).data()
                        self.on_button_click(button_attrs, record_id);
                    }
                }
            }
        });
    },

    do_search: function (domains, contexts, group_by) {
        var self = this;
        this.rpc('/base/session/eval_domain_and_context', {
            domains: domains,
            contexts: contexts,
            group_by_seq: group_by
        }, function (results) {
	        self.group_by_field = false;
	        self.datagroup = new openerp.base.DataGroup(self, self.model, results.domain, results.context, results.group_by || []);
            self.dataset.context = results.context;
            self.dataset.domain = results.domain;
	        self.datagroup.list([],
	            function (groups) {
                    self.groups = groups;
	                if (group_by.length >= 1) {
	                    self.group_by_field = group_by[0].group_by;
	                    self.do_render_group(groups);
	                }
	            },
	            function (dataset) {
	                self.dataset.read_slice(false, false, false, function(records) {
	                    self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
	                    self.$element.find("#kanbanview").remove();
	                    self.on_show_data(self.all_display_data);
	                });
	            }
	        );

        });
    },

    do_render_group : function(datagroups){
        this.all_display_data = [];
        var self = this;
        _.each(datagroups, function (group) {
            self.dataset.context = group.context;
            self.dataset.domain = group.domain;
            var group_name = group.value;
            var group_value = group.value;
            if(!group.value) {
                group_name = "Undefined";
                group_value = 'false';
            }
            else if(group.value instanceof Array) {
                group_name = group.value[1]
                group_value = group.value[0]
            }
	        self.dataset.read_slice(false, false, false, function(records) {
                self.all_display_data.push({"value" : group_value, "records": records, 'header':group_name, 'ids': self.dataset.ids});
                if (datagroups.length == self.all_display_data.length) {
                    self.$element.find("#kanbanview").remove();
                    self.on_show_data(self.all_display_data);
	            }
	        });
        });
    },

    do_show: function () {
        this.$element.show();
    },

    do_hide: function () {
        this.$element.hide();
    },

});
};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<commit_msg>[IMP] kanban view:- fix problem of multiple time reload view on button click.<commit_after>openerp.base_kanban = function (openerp) {
QWeb.add_template('/base_kanban/static/src/xml/base_kanban.xml');
openerp.base.views.add('kanban', 'openerp.base_kanban.KanbanView');
openerp.base_kanban.KanbanView = openerp.base.View.extend({

    init: function(parent, element_id, dataset, view_id) {
        this._super(parent, element_id);
        this.view_manager = parent;
        this.dataset = dataset;
        this.model = this.dataset.model;
        this.view_id = view_id;
        this.group_by_field = false;
        this.source_index = {};
        this.all_display_data = false;
        this.groups = [];
    },

    start: function() {
        this.rpc("/base_kanban/kanbanview/load",
        {"model": this.model, "view_id": this.view_id}, this.on_loaded);
    },
    on_loaded: function(data) {
        var self = this;
        this.template_xml = '';
        this.columns = data.all_fields;
        _.each(data.fields_view.arch.children, function(child) {
            if (child.tag == "template"){
                self.template_xml = openerp.base.json_node_to_xml(child, true)
            }
        });
        if(this.template_xml){
            self.dataset.read_slice([], 0, false, function (records) {
                self.all_display_data = [{'records': records, 'value':false, 'header': false, 'ids': self.dataset.ids}];
                self.on_show_data(self.all_display_data);
	        });
	    }
    },

    on_show_data: function(datas) {
        var self = this;
        this.all_records = [];
        var new_qweb = new QWeb2.Engine();
		self.$element.html(QWeb.render("KanbanBiew", {"datas" :datas}));
        this.on_reload_kanban();
		this.$element.find(".oe_column").sortable({
		    connectWith: ".oe_column",
		    start: function(event, ui) {
                self.source_index['index'] = ui.item.index();
                self.source_index['column'] = ui.item.parent().attr('id');
            },
		    stop: self.on_recieve_record,
		});
		this.$element.find(".record").addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
		    .find(".record-header")
		        .addClass("ui-widget-header ui-corner-all")
		        .prepend( "")
		        .end()
		    .find( ".record-content" );

		this.$element.find(".record-header .ui-icon").click(function() {
		    $(this).toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
		    $(this).parents(".record:first").find(".record-content").toggle();
		});
		this.$element.find('.record .ui-icon-closethick').click(this.on_close_action);
		this.$element.find(".oe_column").disableSelection();
    },

    on_button_click: function(button_attrs, record_id){
        var self = this;
        if(this.groups.length){
            _.each(this.groups, function (group) {
                self.dataset.context = group.context;
                self.dataset.domain = group.domain;
                self.dataset.read_slice(false, false, false, function(records) {
                    var index = parseInt(_.indexOf(self.dataset.ids, record_id));
                    if(index >= 0) {
                        self.on_confirm_click(button_attrs, index, record_id);
                        return false;
                    }
                });
            });
        } else{
            var index = parseInt(_.indexOf(self.dataset.ids, record_id));
            if(index >= 0) {
                self.on_confirm_click(button_attrs, index, record_id)
            }
        }
    },

    on_confirm_click: function(button_attrs, index, record_id){
        if(button_attrs.type == 'edit') {
            this.select_record(index);
        } else{
            this.on_execute_button_click(button_attrs, record_id)
        }
    },

    select_record:function (index) {
        if(this.view_manager) {
            this.dataset.index = index;
            this.view_manager.on_mode_switch('form');
        }
    },

    do_delete: function (id) {
        var self = this;
        return $.when(this.dataset.unlink([id])).then(function () {
            self.drop_records(id);
        });
    },

    drop_records: function (id) {
        var self = this;
        _.each(self.all_display_data, function(data, index) {
            _.each(data.records, function(record, index_row) {
                if(parseInt(record.id) == id) {
                    self.all_display_data[index]['records'].splice(index_row, 1)
                    return false;
                }
            });
        });
        self.$element.find("#main_" + id).remove()
    },

    on_execute_button_click: function(button_attrs, record_id) {
        var self = this;
        this.execute_action(
            button_attrs, this.dataset, this.session.action_manager,
            record_id, function () {
                var count = 1;
                _.each(self.all_display_data, function(data, index) {
                    self.dataset.read_ids( data.ids, [], function(records){
                        self.all_display_data[index].records = records;
                        if(self.all_display_data.length == count) {
                            self.on_reload_kanban();
                        }
                        count++;
                    });
                });
            }
        );
    },

    on_close_action: function(e) {
        var record_id = $(e.currentTarget).parents('.record:first').attr("id")
        if(record_id) {
            record_id = parseInt(record_id.split("_")[1])
            if(record_id) {
                this.do_delete(record_id);
            }
        }
    },

    on_recieve_record: function(event, ui) {
        var self = this;
        var from = ui.item.index();
        this.flag = false;
        var to = ui.item.prev().index() || 0;
        if(!ui.item.attr("id")){
            return false;
        }
        if(self.columns.sequence && self.source_index.index && self.source_index.index != from) {
	        var child_record = ui.item.parent().children();
	        var data, sequence = 1, index = to;
	        child_record.splice(0, to);
	        if(to >= 0 && child_record) {
	            var record_id = child_record.attr('id').split("_");
	            if(record_id.length >= 2) {
		            _.each(self.all_records, function(record){
		                if(parseInt(record_id[1]) == record.id && record.sequence) {
		                    sequence = record.sequence;
		                    return false;
		                }
		            });
	            }
	        }
	        _.each(child_record, function (child) {
	            var child_id = parseInt($(child).attr("id").split("_")[1]);
	            if(child_id) {
	                _.each(self.all_display_data, function(data, index) {
	                    _.each(data.records, function(record, index_row) {
	                        if(parseInt(record.id) == child_id) {
	                            self.all_display_data[index]['records'][index_row]['sequence'] = sequence;
	                            return false;
	                        }
	                    });
	                });
	                self.dataset.write(child_id, {sequence: sequence});
	                sequence++;
	                self.flag = true;
	            }
	        });
        }
        if(self.group_by_field && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) {
            var value = ui.item.closest("td").attr("id")
            if(value) {
                var data_val = {};
                var wirte_id = parseInt(ui.item.attr("id").split("_")[1]);
                value = value.split("_")[1];
                if(value == 'false') {
                    value = false;
                }
                var update_record = false;
                _.each(self.all_display_data, function(data, index) {
                    _.each(data.records, function(record, index_row) {
                        if(parseInt(record.id) == wirte_id) {
                            self.all_display_data[index]['records'][index_row][self.group_by_field] = value;
                            update_record = self.all_display_data[index]['records'].splice(index_row,1)
                            return false;
                        }
                    });
                });
                _.each(self.all_display_data, function(data, index) {
                    if (data.value == value || (data.value == 'false' && value == false)) {
                        self.all_display_data[index]['records'].push(update_record[0]);
                    }
                });
                data_val[self.group_by_field] = value;
                self.dataset.write(wirte_id, data_val);
                self.flag = true;
            }
        }
        if(self.flag) {
            self.on_reload_kanban();
        }
        this.source_index = {};
    },

    on_reload_kanban: function(){
        var self = this;
        var new_qweb = new QWeb2.Engine();
        this.all_records = []
        new_qweb.add_template('<templates><t t-name="custom_template">' + this.template_xml + '</t></templates>')
        _.each(self.all_display_data, function(data, index) {
            if(data.records.length > 0){
                _.each(data.records, function(record) {
                    self.$element.find("#data_" + record.id).children().remove()
                    self.$element.find("#data_" + record.id).append(new_qweb.render('custom_template', record));
                    self.all_records.push(record);
	            });
            }
            else{
                self.$element.find("#column_" + data.value).remove();
                self.all_display_data.splice(index, 1);
            }
        });
        this.$element.find( ".oe_table_column " ).css("width", 99 / self.all_display_data.length +"%");
        this.$element.find('button').click(function(){
            var record_id = $(this).closest(".record").attr("id");
            if(record_id) {
                record_id = parseInt(record_id.split("_")[1])
                if(record_id) {
                    if($(this).data("type") == "delete") {
                        self.do_delete(record_id);
                    }
                    else{
                        var button_attrs = $(this).data()
                        self.on_button_click(button_attrs, record_id);
                    }
                }
            }
        });
    },

    do_search: function (domains, contexts, group_by) {
        var self = this;
        this.rpc('/base/session/eval_domain_and_context', {
            domains: domains,
            contexts: contexts,
            group_by_seq: group_by
        }, function (results) {
	        self.group_by_field = false;
	        self.datagroup = new openerp.base.DataGroup(self, self.model, results.domain, results.context, results.group_by || []);
            self.dataset.context = results.context;
            self.dataset.domain = results.domain;
	        self.datagroup.list([],
	            function (groups) {
                    self.groups = groups;
	                if (group_by.length >= 1) {
	                    self.group_by_field = group_by[0].group_by;
	                    self.do_render_group(groups);
	                }
	            },
	            function (dataset) {
	                self.dataset.read_slice(false, false, false, function(records) {
	                    self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
	                    self.$element.find("#kanbanview").remove();
	                    self.on_show_data(self.all_display_data);
	                });
	            }
	        );

        });
    },

    do_render_group : function(datagroups){
        this.all_display_data = [];
        var self = this;
        _.each(datagroups, function (group) {
            self.dataset.context = group.context;
            self.dataset.domain = group.domain;
            var group_name = group.value;
            var group_value = group.value;
            if(!group.value) {
                group_name = "Undefined";
                group_value = 'false';
            }
            else if(group.value instanceof Array) {
                group_name = group.value[1]
                group_value = group.value[0]
            }
	        self.dataset.read_slice(false, false, false, function(records) {
                self.all_display_data.push({"value" : group_value, "records": records, 'header':group_name, 'ids': self.dataset.ids});
                if (datagroups.length == self.all_display_data.length) {
                    self.$element.find("#kanbanview").remove();
                    self.on_show_data(self.all_display_data);
	            }
	        });
        });
    },

    do_show: function () {
        this.$element.show();
    },

    do_hide: function () {
        this.$element.hide();
    },

});
};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<|endoftext|>


<commit_before>/**
 * Game Controller
 */
function GameController()
{
    var controller = this;

    this.games = new Collection([], 'name');

    this.onDie         = this.onDie.bind(this);
    this.onAngle       = this.onAngle.bind(this);
    this.onPosition    = this.onPosition.bind(this);
    this.onPrinting    = this.onPrinting.bind(this);
    this.onPoint       = this.onPoint.bind(this);
    this.onScore       = this.onScore.bind(this);
    this.onTrailClear  = this.onTrailClear.bind(this);
    this.onRoundNew    = this.onRoundNew.bind(this);
    this.onRoundEnd    = this.onRoundEnd.bind(this);
    this.onRoundWinner = this.onRoundWinner.bind(this);
    this.onEnd         = this.onEnd.bind(this);

    this.callbacks = {
        onGameLoaded: function () { controller.onGameLoaded(this); },
        onMove: function (data) { controller.onMove(this, data); },
    };
}

/**
 * Add game
 *
 * @param {Game} game
 */
GameController.prototype.addGame = function(game)
{
    if (this.games.add(game)) {
        game.on('end', this.onEnd);
        game.on('round:new', this.onRoundNew);
        game.on('round:end', this.onRoundEnd);
        game.on('round:winner', this.onRoundWinner);

        for (var i = game.clients.items.length - 1; i >= 0; i--) {
            this.attach(game.clients.items[i], game);
        }
    }
};

/**
 * Remove game
 *
 * @param {Game} game
 */
GameController.prototype.removeGame = function(game)
{
    if (this.games.remove(game)) {
        game.removeListener('end', this.onEnd);
        game.removeListener('round:new', this.onRoundNew);
        game.removeListener('round:end', this.onRoundEnd);
        game.removeListener('round:winner', this.onRoundWinner);

        for (var i = game.clients.items.length - 1; i >= 0; i--) {
            this.detach(game.clients.items[i], game);
        }
    }
};

/**
 * Attach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.attach = function(client, game)
{
    this.attachEvents(client);
};

/**
 * Attach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.detach = function(client)
{
    this.detachEvents(client);

    var avatar;

    if (client.room.game) {
        for (var i = client.players.items.length - 1; i >= 0; i--) {
            avatar = client.players.items[i].avatar;
            client.room.game.client.addEvent('game:leave', {avatar: avatar.name});
            client.room.game.removeAvatar(avatar);
        }
    }
};

/**
 * Detach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.attachEvents = function(client)
{
    var controller = this,
        avatar;

    client.on('loaded', this.callbacks.onGameLoaded);
    client.on('player:move', this.callbacks.onMove);

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;

        avatar.on('die', this.onDie);
        avatar.on('angle', this.onAngle);
        avatar.on('position', this.onPosition);
        avatar.on('printing', this.onPrinting);
        avatar.on('point', this.onPoint);
        avatar.on('score', this.onScore);
        avatar.trail.on('clear', this.onTrailClear);
    }
};

/**
 * Detach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.detachEvents = function(client)
{
    var avatar;

    client.removeListener('loaded', this.callbacks.onGameLoaded);
    client.removeListener('player:move', this.callbacks.onMove);

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;

        avatar.removeListener('die', this.onDie);
        avatar.removeListener('angle', this.onAngle);
        avatar.removeListener('position', this.onPosition);
        avatar.removeListener('printing', this.onPrinting);
        avatar.removeListener('point', this.onPoint);
        avatar.removeListener('score', this.onScore);
        avatar.trail.removeListener('clear', this.onTrailClear);
    }
};

/**
 * On game loaded
 *
 * @param {SocketClient} client
 */
GameController.prototype.onGameLoaded = function(client)
{
    var game = client.room.game,
        avatar;

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;
        avatar.ready = true;
    }

    if (game.isReady()) {
        game.newRound();
    }
};

/**
 * On move
 *
 * @param {SocketClient} client
 * @param {Number} move
 */
GameController.prototype.onMove = function(client, data)
{
    var player = client.players.getById(data.avatar);

    if (player && player.avatar) {
        player.avatar.setAngularVelocity(data.move);
    }
};

/**
 * On position
 *
 * @param {Object} data
 */
GameController.prototype.onPosition = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        point = data.point;

    game.client.addEvent('position', {avatar: avatar.name, point: point});
};

/**
 * On printing
 *
 * @param {Object} data
 */
GameController.prototype.onPrinting = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        printing = data.printing;

    game.client.addEvent('printing', {avatar: avatar.name, printing: printing});
};

/**
 * On angle
 *
 * @param {Object} data
 */
GameController.prototype.onAngle = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        angle = data.angle;

    if(!avatar.player.client.room.game.isPlaying()) {
        game.client.addEvent('angle', {avatar: avatar.name, angle: angle});
    }
};

/**
 * On point
 *
 * @param {Object} data
 */
GameController.prototype.onPoint = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        point = data.point;

    if (data.important) {
        game.client.addEvent('point', {avatar: avatar.name, point: point});
    }
};

/**
 * On die
 *
 * @param {Object} data
 */
GameController.prototype.onDie = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game;

    game.client.addEvent('die', {avatar: avatar.name});
};

/**
 * On score
 *
 * @param {Object} data
 */
GameController.prototype.onScore = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        score = data.score;

    game.client.addEvent('score', {avatar: avatar.name, score: score});
};

/**
 * On point
 *
 * @param {Object} data
 */
GameController.prototype.onTrailClear = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game;

    game.client.addEvent('trail:clear', {avatar: avatar.name});
};

// Game events:

/**
 * On round new
 *
 * @param {Object} data
 */
GameController.prototype.onRoundNew = function(data)
{
    data.game.client.addEvent('round:new');
};

/**
 * On round new
 *
 * @param {Object} data
 */
GameController.prototype.onRoundEnd = function(data)
{
    data.game.client.addEvent('round:end');
};

/**
 * On round winner
 *
 * @param {Object} data
 */
GameController.prototype.onRoundWinner = function(data)
{
    data.game.client.addEvent('round:winner', {winner: data.winner.name});
};

/**
 * On end
 *
 * @param {Object} data
 */
GameController.prototype.onEnd = function(data)
{
    data.game.client.addEvent('end');
};
<commit_msg>add binding on bonus:pop and bonus:clean<commit_after>/**
 * Game Controller
 */
function GameController()
{
    var controller = this;

    this.games = new Collection([], 'name');

    this.onDie         = this.onDie.bind(this);
    this.onAngle       = this.onAngle.bind(this);
    this.onPosition    = this.onPosition.bind(this);
    this.onPrinting    = this.onPrinting.bind(this);
    this.onPoint       = this.onPoint.bind(this);
    this.onScore       = this.onScore.bind(this);
    this.onTrailClear  = this.onTrailClear.bind(this);
    this.onRoundNew    = this.onRoundNew.bind(this);
    this.onRoundEnd    = this.onRoundEnd.bind(this);
    this.onRoundWinner = this.onRoundWinner.bind(this);
    this.onEnd         = this.onEnd.bind(this);

    this.callbacks = {
        onGameLoaded: function () { controller.onGameLoaded(this); },
        onMove: function (data) { controller.onMove(this, data); },
    };
}

/**
 * Add game
 *
 * @param {Game} game
 */
GameController.prototype.addGame = function(game)
{
    if (this.games.add(game)) {
        game.on('end', this.onEnd);
        game.on('round:new', this.onRoundNew);
        game.on('round:end', this.onRoundEnd);
        game.on('round:winner', this.onRoundWinner);
<<<<<<< refs/heads/develop

        for (var i = game.clients.items.length - 1; i >= 0; i--) {
            this.attach(game.clients.items[i], game);
        }
    }
};

/**
 * Remove game
 *
 * @param {Game} game
 */
GameController.prototype.removeGame = function(game)
{
    if (this.games.remove(game)) {
        game.removeListener('end', this.onEnd);
        game.removeListener('round:new', this.onRoundNew);
        game.removeListener('round:end', this.onRoundEnd);
        game.removeListener('round:winner', this.onRoundWinner);

        for (var i = game.clients.items.length - 1; i >= 0; i--) {
            this.detach(game.clients.items[i], game);
        }
=======
        game.on('end', this.onEnd);

        game.on('bonus:pop', this.onBonusPop);
        game.on('bonus:clear', this.onBonusClear);
>>>>>>> HEAD~28
    }
};

/**
 * Attach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.attach = function(client, game)
{
    this.attachEvents(client);
};

/**
 * Attach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.detach = function(client)
{
    this.detachEvents(client);

    var avatar;

    if (client.room.game) {
        for (var i = client.players.items.length - 1; i >= 0; i--) {
            avatar = client.players.items[i].avatar;
            client.room.game.client.addEvent('game:leave', {avatar: avatar.name});
            client.room.game.removeAvatar(avatar);
        }
    }
};

/**
 * Detach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.attachEvents = function(client)
{
    var controller = this,
        avatar;

    client.on('loaded', this.callbacks.onGameLoaded);
    client.on('player:move', this.callbacks.onMove);

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;

        avatar.on('die', this.onDie);
        avatar.on('angle', this.onAngle);
        avatar.on('position', this.onPosition);
        avatar.on('printing', this.onPrinting);
        avatar.on('point', this.onPoint);
        avatar.on('score', this.onScore);
        avatar.trail.on('clear', this.onTrailClear);
    }
};

/**
 * Detach events
 *
 * @param {SocketClient} client
 */
GameController.prototype.detachEvents = function(client)
{
    var avatar;

    client.removeListener('loaded', this.callbacks.onGameLoaded);
    client.removeListener('player:move', this.callbacks.onMove);

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;

        avatar.removeListener('die', this.onDie);
        avatar.removeListener('angle', this.onAngle);
        avatar.removeListener('position', this.onPosition);
        avatar.removeListener('printing', this.onPrinting);
        avatar.removeListener('point', this.onPoint);
        avatar.removeListener('score', this.onScore);
        avatar.trail.removeListener('clear', this.onTrailClear);
    }
};

/**
 * On game loaded
 *
 * @param {SocketClient} client
 */
GameController.prototype.onGameLoaded = function(client)
{
    var game = client.room.game,
        avatar;

    for (var i = client.players.items.length - 1; i >= 0; i--) {
        avatar = client.players.items[i].avatar;
        avatar.ready = true;
    }

    if (game.isReady()) {
        game.newRound();
    }
};

/**
 * On move
 *
 * @param {SocketClient} client
 * @param {Number} move
 */
GameController.prototype.onMove = function(client, data)
{
    var player = client.players.getById(data.avatar);

    if (player && player.avatar) {
        player.avatar.setAngularVelocity(data.move);
    }
};

/**
 * On position
 *
 * @param {Object} data
 */
GameController.prototype.onPosition = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        point = data.point;

    game.client.addEvent('position', {avatar: avatar.name, point: point});
};

/**
 * On printing
 *
 * @param {Object} data
 */
GameController.prototype.onPrinting = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        printing = data.printing;

    game.client.addEvent('printing', {avatar: avatar.name, printing: printing});
};

/**
 * On angle
 *
 * @param {Object} data
 */
GameController.prototype.onAngle = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        angle = data.angle;

    if(!avatar.player.client.room.game.isPlaying()) {
        game.client.addEvent('angle', {avatar: avatar.name, angle: angle});
    }
};

/**
 * On point
 *
 * @param {Object} data
 */
GameController.prototype.onPoint = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        point = data.point;

    if (data.important) {
        game.client.addEvent('point', {avatar: avatar.name, point: point});
    }
};

/**
 * On die
 *
 * @param {Object} data
 */
GameController.prototype.onDie = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game;

    game.client.addEvent('die', {avatar: avatar.name});
};

/**
 * On bonus pop
 *
 * @param {SocketClient} game
 */
GameController.prototype.onBonusPop = function(client, data)
{
    var game = data.game,
        channel = data.game.channel;

    this.io.sockets.in(channel).emit('bonus:pop', data.bonus);
};

/**
 * On bonus clear
 *
 * @param {SocketClient}client
 * @param data
 */
GameController.prototype.onBonusClear = function(client, data)
{
    var game = data.game,
        channel = data.game.channel;

    this.io.sockets.in(channel).emit('bonus:clear', data.bonus);
};

/**
 * On score
 *
 * @param {Object} data
 */
GameController.prototype.onScore = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game,
        score = data.score;

    game.client.addEvent('score', {avatar: avatar.name, score: score});
};

/**
 * On point
 *
 * @param {Object} data
 */
GameController.prototype.onTrailClear = function(data)
{
    var avatar = data.avatar,
        game = avatar.player.client.room.game;

    game.client.addEvent('trail:clear', {avatar: avatar.name});
};

// Game events:

/**
 * On round new
 *
 * @param {Object} data
 */
GameController.prototype.onRoundNew = function(data)
{
    data.game.client.addEvent('round:new');
};

/**
 * On round new
 *
 * @param {Object} data
 */
GameController.prototype.onRoundEnd = function(data)
{
    data.game.client.addEvent('round:end');
};

/**
 * On round winner
 *
 * @param {Object} data
 */
GameController.prototype.onRoundWinner = function(data)
{
    data.game.client.addEvent('round:winner', {winner: data.winner.name});
};

/**
 * On end
 *
 * @param {Object} data
 */
GameController.prototype.onEnd = function(data)
{
    data.game.client.addEvent('end');
};
<|endoftext|>


<commit_before>import superagent from 'superagent'
import Express from 'express'
var loginRouter = Express.Router()
import { isEmptyObject } from '../../containers/Login/module/login'
import APIClient from '../../helpers/APIClient'
import projectConfig from '../../../project.config'

loginRouter.get('/idcard', (req, res) => {
    superagent.get('http://idcard.market.alicloudapi.com/lianzhuo/idcard')
        .set('Authorization', `APPCODE ${projectConfig.appCode}`)
        .query(req.query)
        .end((err, { body } = {}) => {
            if (err) {
                res.status(400).send(body || err)
            } else {
                res.status(200).send(body)
            }
        })
})

loginRouter.get('/wechat', (req, res) => {
    const { code } = req.query;
    if (code) {
        console.log('wechat code', code)
        getWechatToken(code)
            .then((tokenInfo) => getWechatUserInfo(tokenInfo))
            .then((weChatUserInfo) => getUserInfo(weChatUserInfo))
            .then((userInfo) => { res.json({ code: 10000, message: 'success', data: userInfo}) })
            .catch((err) => { res.json(Object.assign({ code: 10001 }, data: err)) })
    } else {
        res.json({ code: 10001, message: '缺少参数'})
    }
})

export default loginRouter

function getWechatToken(code) {
    const tokenUrl = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${projectConfig.wechatAppID}&secret=${projectConfig.wechatAppSecret}&code=${code}&grant_type=authorization_code`;
    return new Promise((resolve, reject) => {
        superagent.get(tokenUrl)
            .end((err, res) => {
                const body = JSON.parse(res.text)
                if (err || Object.prototype.hasOwnProperty.call(body, 'errcode')) {
                    reject({ message: '根据code获取微信token失败', data: body})
                } else {
                    resolve(body)
                }
            })
    })
}

function getWechatUserInfo(tokenInfo) {
    const userInfoUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${tokenInfo.access_token}&openid=${tokenInfo.openid}&lang=zh_CN`;
    return new Promise((resolve, reject) => {
        superagent.get(userInfoUrl)
            .end((err, res) => {
                const body = JSON.parse(res.text)
                if (err || Object.prototype.hasOwnProperty.call(body, 'errcode')) {
                    reject({ message: '根据token获取微信信息失败', data: body})
                } else {
                    resolve({ weChatUserInfo: body, accessToken: tokenInfo.access_token })
                }
            })
    })
}

function getUserInfo({ weChatUserInfo, accessToken } = {}) {
    const data = {
        auth_token: accessToken,
        union_id: weChatUserInfo.unionid
    }
    return new Promise((resolve, reject) => {
        let baseUrl = __DEV__ ? projectConfig.devBaseUrl : projectConfig.baseUrl
        const linkAccountUrl = baseUrl + '/api/v1/users/login/linked_account'
        superagent.post(linkAccountUrl)
            .send(data)
            .end((err, { body, text } = {}) => {
                const resBody = isEmptyObject(body) ? JSON.parse(text) : body
                console.log(resBody)
                if (err || Object.prototype.hasOwnProperty.call(resBody, 'code')) resolve({ weChatUserInfo, userError: resBody })
                resolve({ weChatUserInfo, userInfo: resBody })
            })
    })
}
<commit_msg>调整了微信登录<commit_after>import superagent from 'superagent'
import Express from 'express'
var loginRouter = Express.Router()
import { isEmptyObject } from '../../containers/Login/module/login'
import APIClient from '../../helpers/APIClient'
import projectConfig from '../../../project.config'

loginRouter.get('/idcard', (req, res) => {
    superagent.get('http://idcard.market.alicloudapi.com/lianzhuo/idcard')
        .set('Authorization', `APPCODE ${projectConfig.appCode}`)
        .query(req.query)
        .end((err, { body } = {}) => {
            if (err) {
                res.status(400).send(body || err)
            } else {
                res.status(200).send(body)
            }
        })
})

loginRouter.get('/wechat', (req, res) => {
    const { code } = req.query;
    if (code) {
        console.log('wechat code', code)
        getWechatToken(code)
            .then((tokenInfo) => getWechatUserInfo(tokenInfo))
            .then((weChatUserInfo) => getUserInfo(weChatUserInfo))
            .then((userInfo) => { res.json({ code: 10000, message: 'success', data: userInfo}) })
            .catch((err) => { res.json(Object.assign({ code: 10001 }, data: err)) })
    } else {
        res.json({ code: 10001, message: '缺少参数'})
    }
})

export default loginRouter

function getWechatToken(code) {
    const tokenUrl = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${projectConfig.wechatAppID}&secret=${projectConfig.wechatAppSecret}&code=${code}&grant_type=authorization_code`;
    return new Promise((resolve, reject) => {
        superagent.get(tokenUrl)
            .end((err, res) => {
                const body = JSON.parse(res.text)
                if (err || Object.prototype.hasOwnProperty.call(body, 'errcode')) {
                    reject({ message: '根据code获取微信token失败', data: body})
                } else {
                    resolve(body)
                }
            })
    })
}

function getWechatUserInfo(tokenInfo) {
    const userInfoUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${tokenInfo.access_token}&openid=${tokenInfo.openid}&lang=zh_CN`;
    return new Promise((resolve, reject) => {
        superagent.get(userInfoUrl)
            .end((err, res) => {
                const body = JSON.parse(res.text)
                if (err || Object.prototype.hasOwnProperty.call(body, 'errcode')) {
                    reject({ message: '根据token获取微信信息失败', data: body})
                } else {
                    resolve({ weChatUserInfo: body, accessToken: tokenInfo.access_token })
                }
            })
    })
}

function getUserInfo(weChatInfo) {
    const { weChatUserInfo, accessToken } = weChatInfo
    const data = {
        auth_token: accessToken,
        union_id: weChatUserInfo.unionid
    }
    return new Promise((resolve, reject) => {
        let baseUrl = __DEV__ ? projectConfig.devBaseUrl : projectConfig.baseUrl
        const linkAccountUrl = baseUrl + '/api/v1/users/login/linked_account'
        superagent.post(linkAccountUrl)
            .send(data)
            .end((err, { body, text } = {}) => {
                const resBody = isEmptyObject(body) ? JSON.parse(text) : body
                console.log(resBody)
                if (err || Object.prototype.hasOwnProperty.call(resBody, 'code')) resolve({ weChatUserInfo: weChatUserInfo, userError: resBody })
                resolve({ weChatUserInfo: weChatUserInfo, userInfo: resBody })
            })
    })
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types'
import Row from "./Row";
import questions from '../../bundles/SellerRegistration/components/DisclosuresForm/questions';
import isEmpty from 'lodash/isEmpty';
import format from 'date-fns/format';
import startCase from 'lodash/startCase';

import './SellerProfile.css';

const documentTitle = {
    financial: 'Financial Statement',
    liability: 'Public Liability Insurance',
    workers: 'Workers Compensation Insurance'
};

const govExperienceTitle = {
    no_experience: "None yet",
    local: "Local government",
    state: "State/territory government",
    federal: "Federal/Commonwealth government",
    international: "International government"
}

const PrivateInfo = (props) => {
    const {
        documents = {},
        documentsUrl,
        case_studies = {},
        number_of_employees,
        government_experience,
        other_panels,
        signed_agreements = [],
        recruiter_info = {},
        pricing = {},
        all_domains = []
    } = props;

    let price_statuses = {};
    all_domains.forEach(d => price_statuses[d.domain_name] = d.price_status);

    return (

 PRIVATE INFORMATION FOR DIGITAL MARKETPLACE ASSESSMENT PURPOSES ONLY

            <Row title="Case Study Referees" show={true}>
                {case_studies && Object.keys(case_studies).map((study, i) => {
                    const {title, referee_name, refereeName, referee_email, refereeEmail, referee_position, refereePosition} = case_studies[study];
                    return (
Case Study: "{title}"
 Referee: {referee_name || refereeName}
                        ({referee_position || refereePosition}) {referee_email || refereeEmail}

)
                })
                }
            </Row>
            <Row title="Business Details" show={true}>
                Number of Employees: {number_of_employees}

                Government experience:

                {Object.keys(government_experience).map((key, i) => {
                    return (
{govExperienceTitle[key]}
)
                })
                }

                {other_panels &&
Other panels: {other_panels}
}
            </Row>
            <Row title="Disclosures" show={true}>
                {Object.keys(questions).map((key, i) => {
                    const question = questions[key];
                    const answer = props['disclosures'][key];
                    const details = props['disclosures'][key + "_details"];
                    return (
{question} {answer} - {details}
)
                })}
            </Row>
            <Row title="Master Agreement" show={!isEmpty(signed_agreements)}>
                {signed_agreements.map((sa, i) => {
                    const { htmlUrl, pdfUrl, signedAt, user } = sa
                    return (
Master Agreement signed
                        at {format(new Date(signedAt), 'YYYY-MM-DD HH:mm')} by {user.name} ({user.emailAddress})

)
                })}
            </Row>
            <Row title="Documents" show={!isEmpty(documents)}>

                        Document type
                        Expiry

                    {Object.keys(documents).map((key, val) => {
                        const {filename, expiry, application_id, noWorkersCompensation} = documents[key];
                        const url = application_id ? `/admin/application/${application_id}/documents/` : documentsUrl
                        return (

                                    {key == 'workers' && noWorkersCompensation
                                        ? documentTitle[key]
                                        : <a href={`${url}${filename}`}>{documentTitle[key]}
                                    }

                                    {expiry && format(new Date(expiry), 'DD/MM/YYYY')}

                        )
                    })}

                {documents && documents.workers && documents.workers.noWorkersCompensation &&

                        Workers compensation insurance not held by this seller

                }
            </Row>
            <Row title="Recruiter Info" show={!isEmpty(recruiter_info)}>
              {Object.keys(recruiter_info).map((key, i) => {
                return (

{key}

                    {Object.keys(recruiter_info[key]).map((subKey, j) => {
                      return (
                        <div key={`${key}-${subKey}`}>
                          {startCase(subKey)}:{recruiter_info[key][subKey]}

                      )
                    })}

                )
              })}
            </Row>
            <Row title="Pricing" show={!isEmpty(pricing)}>
              {Object.keys(pricing).map((key, i) => {
                return (

{`${key}: $${pricing[key]['maxPrice']} (${price_statuses[key]})`}

                )
              })}
            </Row>

    )
};

PrivateInfo.propTypes = {
    documents: PropTypes.object,
    documentsUrl: PropTypes.string,
    case_studies: PropTypes.object,
    number_of_employees: PropTypes.string,
    government_experience: PropTypes.object,
    other_panels: PropTypes.string,
    disclosures: PropTypes.object,
    signed_agreements: PropTypes.array,
    recruiter_info: PropTypes.object,
    pricing: PropTypes.object,
    all_domains: PropTypes.array
};

export default PrivateInfo;
<commit_msg>[MAR-4062] null checks (#927)<commit_after>import React from 'react';
import PropTypes from 'prop-types'
import Row from "./Row";
import questions from '../../bundles/SellerRegistration/components/DisclosuresForm/questions';
import isEmpty from 'lodash/isEmpty';
import format from 'date-fns/format';
import startCase from 'lodash/startCase';

import './SellerProfile.css';

const documentTitle = {
    financial: 'Financial Statement',
    liability: 'Public Liability Insurance',
    workers: 'Workers Compensation Insurance'
};

const govExperienceTitle = {
    no_experience: "None yet",
    local: "Local government",
    state: "State/territory government",
    federal: "Federal/Commonwealth government",
    international: "International government"
}

const PrivateInfo = (props) => {
    const {
        documents = {},
        documentsUrl,
        case_studies = {},
        number_of_employees,
        government_experience,
        other_panels,
        signed_agreements = [],
        recruiter_info = {},
        pricing = {},
        all_domains = []
    } = props;

    let price_statuses = {};
    all_domains.forEach(d => price_statuses[d.domain_name] = d.price_status);

    return (

 PRIVATE INFORMATION FOR DIGITAL MARKETPLACE ASSESSMENT PURPOSES ONLY

            <Row title="Case Study Referees" show={true}>
                {case_studies && Object.keys(case_studies).map((study, i) => {
                    const {title, referee_name, refereeName, referee_email, refereeEmail, referee_position, refereePosition} = case_studies[study];
                    return (
Case Study: "{title}"
 Referee: {referee_name || refereeName}
                        ({referee_position || refereePosition}) {referee_email || refereeEmail}

)
                })
                }
            </Row>
            <Row title="Business Details" show={true}>
                Number of Employees: {number_of_employees}

                Government experience:

                {government_experience && Object.keys(government_experience).map((key, i) => {
                    return (
{govExperienceTitle[key]}
)
                })
                }

                {other_panels &&
Other panels: {other_panels}
}
            </Row>
            <Row title="Disclosures" show={true}>
                {questions && Object.keys(questions).map((key, i) => {
                    const question = questions[key];
                    const answer = props['disclosures'][key];
                    const details = props['disclosures'][key + "_details"];
                    return (
{question} {answer} - {details}
)
                })}
            </Row>
            <Row title="Master Agreement" show={!isEmpty(signed_agreements)}>
                {signed_agreements.map((sa, i) => {
                    const { htmlUrl, pdfUrl, signedAt, user } = sa
                    return (
Master Agreement signed
                        at {format(new Date(signedAt), 'YYYY-MM-DD HH:mm')} by {user.name} ({user.emailAddress})

)
                })}
            </Row>
            <Row title="Documents" show={!isEmpty(documents)}>

                        Document type
                        Expiry

                    {Object.keys(documents).map((key, val) => {
                        const {filename, expiry, application_id, noWorkersCompensation} = documents[key];
                        const url = application_id ? `/admin/application/${application_id}/documents/` : documentsUrl
                        return (

                                    {key == 'workers' && noWorkersCompensation
                                        ? documentTitle[key]
                                        : <a href={`${url}${filename}`}>{documentTitle[key]}
                                    }

                                    {expiry && format(new Date(expiry), 'DD/MM/YYYY')}

                        )
                    })}

                {documents && documents.workers && documents.workers.noWorkersCompensation &&

                        Workers compensation insurance not held by this seller

                }
            </Row>
            <Row title="Recruiter Info" show={!isEmpty(recruiter_info)}>
              {Object.keys(recruiter_info).map((key, i) => {
                return (

{key}

                    {Object.keys(recruiter_info[key]).map((subKey, j) => {
                      return (
                        <div key={`${key}-${subKey}`}>
                          {startCase(subKey)}:{recruiter_info[key][subKey]}

                      )
                    })}

                )
              })}
            </Row>
            <Row title="Pricing" show={!isEmpty(pricing)}>
              {Object.keys(pricing).map((key, i) => {
                return (

{`${key}: $${pricing[key]['maxPrice']} (${price_statuses[key]})`}

                )
              })}
            </Row>

    )
};

PrivateInfo.propTypes = {
    documents: PropTypes.object,
    documentsUrl: PropTypes.string,
    case_studies: PropTypes.object,
    number_of_employees: PropTypes.string,
    government_experience: PropTypes.object,
    other_panels: PropTypes.string,
    disclosures: PropTypes.object,
    signed_agreements: PropTypes.array,
    recruiter_info: PropTypes.object,
    pricing: PropTypes.object,
    all_domains: PropTypes.array
};

export default PrivateInfo;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { BaseComponent } from 'shared/components'
import { isEmpty, throttle } from 'lodash'
import Card from 'shared/components/wall/PostCard'
import $ from 'jquery'

export default class PostCards extends BaseComponent {

  constructor (props) {
    super(props)
    this.state = { shouldLoadFunc: false }
  }

  static propTypes = {
    posts: PropTypes.array.isRequired,
    loadFunc: PropTypes.func.isRequired,
    hasMore: PropTypes.bool.isRequired
  }

  getDocHeight () {
    const D = document
    return Math.max(
      Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
      Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
      Math.max(D.body.clientHeight, D.documentElement.clientHeight)
    )
  }

  getOffsetHeight () {
    const D = document
    return Math.max(D.body.offsetHeight, D.documentElement.offsetHeight)
  }

  isScrollToLoad (threshold=1) {
    let elemHeight = this.getDocHeight() - this.getOffsetHeight()
    return $(document).scrollTop() >= parseInt(elemHeight * threshold, 10)
  }

  handleScroll (event) {
    const threshold = 0.7
    if (this.isScrollToLoad(threshold))
      this.setState({ shouldLoadFunc: true })
  }

  componentWillUpdate (nextProps, nextState) {
    if (nextState.shouldLoadFunc && this.props.hasMore) {
      this.setState({ shouldLoadFunc: false })
      this.props.loadFunc()
    }
  }

  componentDidMount () {
    window.addEventListener('scroll', throttle(::this.handleScroll, 300))
  }

  componentWillUnmount () {
    window.removeEventListener('scroll', this.handleScroll)
  }

  render () {
    const cards = this.props.posts
    return (

        {!isEmpty(cards) && cards.map(function (card) {
          return <Card key={card.id} data={card} />
        })}

    )
  }
}
<commit_msg>fix scroll performance<commit_after>import React, { PropTypes } from 'react'
import { BaseComponent } from 'shared/components'
import { isEmpty, throttle } from 'lodash'
import Card from 'shared/components/wall/PostCard'
import $ from 'jquery'

export default class PostCards extends BaseComponent {

  constructor (props) {
    super(props)
    this.state = { shouldLoadFunc: false }
  }

  static propTypes = {
    posts: PropTypes.array.isRequired,
    loadFunc: PropTypes.func.isRequired,
    hasMore: PropTypes.bool.isRequired
  }

  getDocHeight () {
    const D = document
    return Math.max(
      Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
      Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
      Math.max(D.body.clientHeight, D.documentElement.clientHeight)
    )
  }

  getOffsetHeight () {
    const D = document
    return Math.max(D.body.offsetHeight, D.documentElement.offsetHeight)
  }

  isScrollToLoad (threshold=1) {
    let elemHeight = this.getDocHeight() - this.getOffsetHeight()
    return $(document).scrollTop() >= parseInt(elemHeight * threshold, 10)
  }

  handleScroll (event) {
    const threshold = 0.6
    if (this.isScrollToLoad(threshold))
      this.setState({ shouldLoadFunc: true })
  }

  componentWillUpdate (nextProps, nextState) {
    if (nextState.shouldLoadFunc && this.props.hasMore) {
      this.setState({ shouldLoadFunc: false })
      this.props.loadFunc()
    }
  }

  componentDidMount () {
    window.addEventListener('scroll', throttle(::this.handleScroll, 10))
  }

  componentWillUnmount () {
    window.removeEventListener('scroll', this.handleScroll)
  }

  render () {
    const cards = this.props.posts
    return (

        {!isEmpty(cards) && cards.map(function (card) {
          return <Card key={card.id} data={card} />
        })}

    )
  }
}
<|endoftext|>


<commit_before>test(
  'Word Util',

  [
    'ephox.perhaps.Option',
    'ephox.robin.test.Assertions',
    'ephox.robin.util.WordUtil'
  ],

  function (Option, Assertions, WordUtil) {

    var checkNone = function (text, word) {
      var actual = word(text);
      assert.eq(true, actual.isNone());
    };

    var check = function (expected, text, word) {
      var actual = word(text);
      actual.fold(function () {
        assert.fail('Expected: ' + expected + ' but received nothing.');
      }, function (v) {
        assert.eq(expected, v);
      });
    };

    checkNone('ballast', WordUtil.firstWord);
    checkNone('ballast', WordUtil.lastWord);
    check(' one', 'ballast one', WordUtil.lastWord);
    check(' one', 'ballast  one', WordUtil.lastWord);
    check(' d', 'a b c d', WordUtil.lastWord);
    check('one ', 'one ballast', WordUtil.firstWord);
    check('one ', 'one two three ', WordUtil.firstWord);
    check(' ', '  o pp qq', WordUtil.firstWord);
    check('apple ', 'apple bear cat', WordUtil.firstWord);
    check('apple ', 'apple ', WordUtil.firstWord);
  }
);<commit_msg>TBIO-143: unused imports<commit_after>test(
  'Word Util',

  [
    'ephox.robin.util.WordUtil'
  ],

  function (WordUtil) {

    var checkNone = function (text, word) {
      var actual = word(text);
      assert.eq(true, actual.isNone());
    };

    var check = function (expected, text, word) {
      var actual = word(text);
      actual.fold(function () {
        assert.fail('Expected: ' + expected + ' but received nothing.');
      }, function (v) {
        assert.eq(expected, v);
      });
    };

    checkNone('ballast', WordUtil.firstWord);
    checkNone('ballast', WordUtil.lastWord);
    check(' one', 'ballast one', WordUtil.lastWord);
    check(' one', 'ballast  one', WordUtil.lastWord);
    check(' d', 'a b c d', WordUtil.lastWord);
    check('one ', 'one ballast', WordUtil.firstWord);
    check('one ', 'one two three ', WordUtil.firstWord);
    check(' ', '  o pp qq', WordUtil.firstWord);
    check('apple ', 'apple bear cat', WordUtil.firstWord);
    check('apple ', 'apple ', WordUtil.firstWord);
  }
);<|endoftext|>


<commit_before>const animate = function () {
  // set the animation targets
  const banner = document.getElementById('banner');

  // create our TimelineLite object
  const tl = gsap.timeline({ delay: 1 });

  // define the animation
  tl.to(banner, { opacity: 1 })
    .from('txt1', { opacity: 0 })
    .to('txt1', { opacity: 0 }, '+=2')
    .from('txt2', { opacity: 0 }, '+=0.5')
    .from('cta', { opacity: 0 }, '+=1');
};

// instantiate and initialize the ad
const ad = new Ad(animate);
ad.init();
<commit_msg>fix id targets for GSAP<commit_after>const animate = function () {
  // set the animation targets
  const banner = document.getElementById('banner');

  // create our TimelineLite object
  const tl = gsap.timeline({ delay: 1 });

  // define the animation
  tl.to(banner, { opacity: 1 })
    .from('#txt1', { opacity: 0 })
    .to('#txt1', { opacity: 0 }, '+=2')
    .from('#txt2', { opacity: 0 }, '+=0.5')
    .from('#cta', { opacity: 0 }, '+=1');
};

// instantiate and initialize the ad
const ad = new Ad(animate);
ad.init();
<|endoftext|>


<commit_before>import { createAction, handleActions } from 'redux-actions'
import Immutable from 'immutable'
import fetch from 'isomorphic-fetch'

export const FETCH_COLLECTION = 'FETCH_COLLECTION'
export const FETCH_COLLECTION_SUCCESS = 'FETCH_COLLECTION_SUCCESS'
export const FETCH_COLLECTION_FAIL = 'FETCH_COLLECTION_FAIL'

export const ADD_COLLECTION = 'ADD_COLLECTION'
export const ADD_COLLECTION_SUCCESS = 'ADD_COLLECTION_SUCCESS'
export const ADD_COLLECTION_FAIL = 'ADD_COLLECTION_FAIL'

export const UPDATE_COLLECTION = 'UPDATE_COLLECTION'
export const UPDATE_COLLECTION_SUCCESS = 'UPDATE_COLLECTION_SUCCESS'
export const UPDATE_COLLECTION_FAIL = 'UPDATE_COLLECTION_FAIL'

export const DELETE_COLLECTION = 'DELETE_COLLECTION'
export const DELETE_COLLECTION_SUCCESS = 'DELETE_COLLECTION_SUCCESS'
export const DELETE_COLLECTION_FAIL = 'DELETE_COLLECTION_FAIL'

export const getCollectionRequest = createAction(FETCH_COLLECTION, (data) => data)
export const getCollectionSuccess = createAction(FETCH_COLLECTION_SUCCESS, (data) => data)
export const getCollectionFailed = createAction(FETCH_COLLECTION_FAIL, (data) => data)
export const actions = {getCollection}

const initialState = Immutable.fromJS({
  myCollection: null,
  isAdded: false,
  isAdding: false,
  isUpdating: false,
  isUpdated: false,
  isDeleted: false,
  isDeleting: false,
  isFetch: false,
  isFetching: false,
  statusText: null
})

function checkHttpStatus (response) {
  if (response.status >= 200 && response.status < 300) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
}

function parseJSON (response) {
  console.log(response)
  return response.json()
}

function serialize (data) {
  return Object.keys(data).map(function (keyName) {
    return encodeURIComponent(keyName) + '=' + encodeURIComponent(data[keyName])
  }).join('&')
}

export function getCollection () {
  return (dispatch, getState) => {
    dispatch(getCollectionRequest())
    return fetch('//api.cityme.asia/configs/searchCollections', {
      method: 'get',
      headers: {
        'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    }).then(checkHttpStatus)
      .then(parseJSON)
      .then(response => {
        try {
          dispatch(getCollectionSuccess(response))
        } catch (e) {
          dispatch(getCollectionFailed({
            status: 405,
            statusText: 'Parse error'
          }))
        }
      })
    .catch(error => {
      dispatch(getCollectionFailed({
        status: 405,
        statusText: error.message
      }))
    })
  }
}

export default handleActions({
  [FETCH_COLLECTION]: (state, { payload }) => {
    return Object.assign({}, state, {
      isFetching: true
    })
  },
  [FETCH_COLLECTION_SUCCESS]: (state, { payload }) => {
    return Object.assign({}, state, {
      isFetching: false,
      isFetch: true,
      myCollection: payload
    })
  },
  [FETCH_COLLECTION_FAIL]: (state, { payload }) => {
    return Object.assign({}, state, {
      isFetching: false,
      statusText: payload.statusText
    })
  }
}, initialState)
<commit_msg>Update js<commit_after>import { createAction, handleActions } from 'redux-actions'
import Immutable from 'immutable'
import fetch from 'isomorphic-fetch'

export const FETCH_COLLECTION = 'FETCH_COLLECTION'
export const FETCH_COLLECTION_SUCCESS = 'FETCH_COLLECTION_SUCCESS'
export const FETCH_COLLECTION_FAIL = 'FETCH_COLLECTION_FAIL'

export const ADD_COLLECTION = 'ADD_COLLECTION'
export const ADD_COLLECTION_SUCCESS = 'ADD_COLLECTION_SUCCESS'
export const ADD_COLLECTION_FAIL = 'ADD_COLLECTION_FAIL'

export const UPDATE_COLLECTION = 'UPDATE_COLLECTION'
export const UPDATE_COLLECTION_SUCCESS = 'UPDATE_COLLECTION_SUCCESS'
export const UPDATE_COLLECTION_FAIL = 'UPDATE_COLLECTION_FAIL'

export const DELETE_COLLECTION = 'DELETE_COLLECTION'
export const DELETE_COLLECTION_SUCCESS = 'DELETE_COLLECTION_SUCCESS'
export const DELETE_COLLECTION_FAIL = 'DELETE_COLLECTION_FAIL'

export const getCollectionRequest = createAction(FETCH_COLLECTION, (data) => data)
export const getCollectionSuccess = createAction(FETCH_COLLECTION_SUCCESS, (data) => data)
export const getCollectionFailed = createAction(FETCH_COLLECTION_FAIL, (data) => data)
export const actions = {getCollection}

const initialState = Immutable.fromJS({
  myCollection: null,
  isAdded: false,
  isAdding: false,
  isUpdating: false,
  isUpdated: false,
  isDeleted: false,
  isDeleting: false,
  isFetch: false,
  isFetching: false,
  statusText: null
})

function checkHttpStatus (response) {
  if (response.status >= 200 && response.status < 300) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
}

function parseJSON (response) {
  console.log(response)
  return response.json()
}

function serialize (data) {
  return Object.keys(data).map(function (keyName) {
    return encodeURIComponent(keyName) + '=' + encodeURIComponent(data[keyName])
  }).join('&')
}

export function getCollection () {
  return (dispatch, getState) => {
    dispatch(getCollectionRequest())
    return fetch('//api.cityme.asia/configs/searchCollections', {
      method: 'get',
      headers: {
        'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    }).then(checkHttpStatus)
      .then(parseJSON)
      .then(response => {
        try {
          dispatch(getCollectionSuccess(response))
        } catch (e) {
          dispatch(getCollectionFailed({
            status: 405,
            statusText: 'Parse error'
          }))
        }
      })
    .catch(error => {
      dispatch(getCollectionFailed({
        status: 405,
        statusText: error.message
      }))
    })
  }
}

export default handleActions({
  [FETCH_COLLECTION]: (state, { payload }) => {
    return {...state,
      isFetching: true
    }
  },
  [FETCH_COLLECTION_SUCCESS]: (state, { payload }) => {
    return {...state,
      isFetching: false,
      isFetch: true,
      myCollection: payload
    }
  },
  [FETCH_COLLECTION_FAIL]: (state, { payload }) => {
    return {...state,
      isFetching: false,
      statusText: payload.statusText
    }
  }
}, initialState)
<|endoftext|>


<commit_before>/**
 * @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@pm.me>
 *
 * @author Marco Ambrosini <marcoambrosini@pm.me>
 *
 * @license AGPL-3.0-or-later
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

// For API documentation see https://nextcloud-talk.readthedocs.io/en/latest/poll/

/**
 *
 * @param {string} token The conversation token
 * @param {string} question The question of the polln
 * @param {Array} options The options participants can vote for
 * @param {number} resultMode Result mode of the poll
 * @param {number} maxVotes Maximum amount of options a user can vote for, 0 means unlimited
 * @return {object} The poll object
 */
const postNewPoll = async function(token, question, options, resultMode, maxVotes) {
	return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}', { token }), {
		question,
		options,
		resultMode,
		maxVotes,
	})
}

export {
	postNewPoll,
}
<commit_msg>Add request for poll details<commit_after>/**
 * @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@pm.me>
 *
 * @author Marco Ambrosini <marcoambrosini@pm.me>
 *
 * @license AGPL-3.0-or-later
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

// For API documentation see https://nextcloud-talk.readthedocs.io/en/latest/poll/

/**
 *
 * @param {string} token The conversation token
 * @param {string} question The question of the polln
 * @param {Array} options The options participants can vote for
 * @param {number} resultMode Result mode of the poll
 * @param {number} maxVotes Maximum amount of options a user can vote for, 0 means unlimited
 * @return {object} The poll object
 */
const postNewPoll = async function(token, question, options, resultMode, maxVotes) {
	return axios.post(generateOcsUrl('apps/spreed/api/v1/poll/{token}', { token }), {
		question,
		options,
		resultMode,
		maxVotes,
	})
}

/**
 *
 * @param {string} token The conversation token
 * @param {number} pollId ID of the poll
 * @return {object} The poll object
 */
const getPollData = async function(token, pollId) {
	return axios.get(generateOcsUrl('apps/spreed/api/v1/poll/{token}/{pollId}', { token, pollId }))
}

export {
	postNewPoll,
	getPollData,
}
<|endoftext|>


<commit_before>(function(s){var w,f={},o=window,l=console,m=Math,z='postMessage',x='HackTimer.js by turuslan: ',v='Initialisation failed',p=0,r='hasOwnProperty',y=[].slice,b=Worker;try{s=o.URL.createObjectURL(new Blob(["var f={},p=postMessage,r='hasOwnProperty';onmessage=function(e){var d=e.data,i=d.i,t=d[r]('t')?d.t:0;switch(d.n){case'a':f[i]=setInterval(function(){p(i)},t);break;case'b':if(f[r](i)){clearInterval(f[i]);delete f[i]}break;case'c':f[i]=setTimeout(function(){p(i);if(f[r](i))delete f[i]},t);break;case'd':if(f[r](i)){clearTimeout(f[i]);delete f[i]}break}}"]))}catch(e){}if(typeof(b)!=='undefined'){try{w=new b(s);o.setInterval=function(c,t){var i=++p;f[i]={c:c,p:y.call(arguments,2)};w[z]({n:'a',i:i,t:t});return i};o.clearInterval=function(i){if(f[r](i))delete f[i],w[z]({n:'b',i:i})};o.setTimeout=function(c,t){var i=++p;f[i]={c:c,p:y.call(arguments,2)};w[z]({n:'c',i:i,t:t});return i};o.clearTimeout=function(i){if(f[r](i))delete f[i],w[z]({n:'d',i:i})};w.onmessage=function(e){var n=e.data,c;if(f[r](n))n=f[n],c=n.c;if(typeof(c)=='string')try{c=new Function(c)}catch(k){l.log(x+'Error parsing callback code string: ',k)}if(typeof(c)=='function')c.apply(o,n.p)};w.onerror=function(e){l.log(e)};l.log(x+'Initialisation succeeded')}catch(e){l.log(x+v);l.error(e)}}else l.log(x+v+' - HTML5 Web Worker is not supported')})('HackTimerWorker.min.js');<commit_msg>deleted console.log<commit_after>(function(s){var w,f={},o=window,l=console,m=Math,z='postMessage',x='HackTimer.js by turuslan: ',v='Initialisation failed',p=0,r='hasOwnProperty',y=[].slice,b=Worker;try{s=o.URL.createObjectURL(new Blob(["var f={},p=postMessage,r='hasOwnProperty';onmessage=function(e){var d=e.data,i=d.i,t=d[r]('t')?d.t:0;switch(d.n){case'a':f[i]=setInterval(function(){p(i)},t);break;case'b':if(f[r](i)){clearInterval(f[i]);delete f[i]}break;case'c':f[i]=setTimeout(function(){p(i);if(f[r](i))delete f[i]},t);break;case'd':if(f[r](i)){clearTimeout(f[i]);delete f[i]}break}}"]))}catch(e){}if(typeof(b)!=='undefined'){try{w=new b(s);o.setInterval=function(c,t){var i=++p;f[i]={c:c,p:y.call(arguments,2)};w[z]({n:'a',i:i,t:t});return i};o.clearInterval=function(i){if(f[r](i))delete f[i],w[z]({n:'b',i:i})};o.setTimeout=function(c,t){var i=++p;f[i]={c:c,p:y.call(arguments,2)};w[z]({n:'c',i:i,t:t});return i};o.clearTimeout=function(i){if(f[r](i))delete f[i],w[z]({n:'d',i:i})};w.onmessage=function(e){var n=e.data,c;if(f[r](n))n=f[n],c=n.c;if(typeof(c)=='string')try{c=new Function(c)}catch(k){l.log(x+'Error parsing callback code string: ',k)}if(typeof(c)=='function')c.apply(o,n.p)};w.onerror=function(e){l.log(e)};}catch(e){l.log(x+v);l.error(e)}}else l.log(x+v+' - HTML5 Web Worker is not supported')})('HackTimerWorker.min.js');<|endoftext|>


<commit_before>import './styles.css';
import {View} from 'backbone.marionette';
import settings from '../../util/settings';
import template from './TreeView.hbs';
import StatusToggleView from '../status-toggle/StatusToggleView';
import {on} from '../../decorators';
import {behavior} from '../../decorators/index';

@behavior('TooltipBehavior', {position: 'bottom'})
class TreeView extends View {
    template = template;

    initialize({state, tabName, baseUrl}) {
        this.state = state;
        this.baseUrl = baseUrl;
        this.tabName = tabName;
        this.statusesSelect = new StatusToggleView();
        this.listenTo(this.state, 'change:testcase', (m, testcase) => this.highlightItem(testcase));
        this.listenTo(settings, 'change:visibleStatuses', this.render);
        this.listenTo(settings, 'change:showGroupInfo', this.render);
    }

    onDomRefresh() {
        this.$('.node__title_active').parents('.node').toggleClass('node__expanded', true);
    }

    onRender() {
        this.highlightItem(this.state.get('testcase'));
    }

    onDestroy() {
        this.statusesSelect.hide();
    }

    @on('click .node__title')
    onNodeClick(e) {
        this.$(e.currentTarget).parent().toggleClass('node__expanded');
    }

    @on('click .tree__statuses')
    onFilterClick(e) {
        const filter = this.$(e.currentTarget);
        if(this.statusesSelect.isVisible()) {
            this.statusesSelect.hide();
        } else {
            this.statusesSelect.show(filter);
        }
    }

    @on('click .tree__info')
    onInfoClick() {
        const show = settings.get('showGroupInfo');
        settings.save('showGroupInfo', !show);
    }

    highlightItem(uid) {
        this.$('[data-uid]').each((i, node) => {
            const el = this.$(node);
            el.toggleClass('node__title_active', el.data('uid') === uid);
        });
    }

    serializeData() {
        const statuses = settings.get('visibleStatuses');
        const showGroupInfo = settings.get('showGroupInfo');
        return {
            baseUrl: this.baseUrl,
            showGroupInfo: showGroupInfo,
            time: this.collection.time,
            statistic: this.collection.statistic,
            tabName: this.tabName,
            items: this.filterNodes(statuses, this.collection.toJSON())
        };
    }

    filterNodes(statuses, nodes) {
        return nodes
            .map(item => this.mapNode(statuses, item))
            .filter(item => item.type === 'TestCaseNode' ? statuses[item.status] : item.children.length > 0);
    }

    mapNode(statuses, node) {
        if (node.type === 'TestCaseNode') {
            return node;
        }
        return Object.assign({}, node, {
            children: this.filterNodes(statuses, node.children)
        });
    }
}

export default TreeView;
<commit_msg>sort tree nodes by name by default (part of #79)<commit_after>import './styles.css';
import {View} from 'backbone.marionette';
import settings from '../../util/settings';
import template from './TreeView.hbs';
import StatusToggleView from '../status-toggle/StatusToggleView';
import {on} from '../../decorators';
import {behavior} from '../../decorators/index';

@behavior('TooltipBehavior', {position: 'bottom'})
class TreeView extends View {
    template = template;

    initialize({state, tabName, baseUrl}) {
        this.state = state;
        this.baseUrl = baseUrl;
        this.tabName = tabName;
        this.statusesSelect = new StatusToggleView();
        this.listenTo(this.state, 'change:testcase', (m, testcase) => this.highlightItem(testcase));
        this.listenTo(settings, 'change:visibleStatuses', this.render);
        this.listenTo(settings, 'change:showGroupInfo', this.render);
    }

    onDomRefresh() {
        this.$('.node__title_active').parents('.node').toggleClass('node__expanded', true);
    }

    onRender() {
        this.highlightItem(this.state.get('testcase'));
    }

    onDestroy() {
        this.statusesSelect.hide();
    }

    @on('click .node__title')
    onNodeClick(e) {
        this.$(e.currentTarget).parent().toggleClass('node__expanded');
    }

    @on('click .tree__statuses')
    onFilterClick(e) {
        const filter = this.$(e.currentTarget);
        if(this.statusesSelect.isVisible()) {
            this.statusesSelect.hide();
        } else {
            this.statusesSelect.show(filter);
        }
    }

    @on('click .tree__info')
    onInfoClick() {
        const show = settings.get('showGroupInfo');
        settings.save('showGroupInfo', !show);
    }

    highlightItem(uid) {
        this.$('[data-uid]').each((i, node) => {
            const el = this.$(node);
            el.toggleClass('node__title_active', el.data('uid') === uid);
        });
    }

    serializeData() {
        const statuses = settings.get('visibleStatuses');
        const showGroupInfo = settings.get('showGroupInfo');
        return {
            baseUrl: this.baseUrl,
            showGroupInfo: showGroupInfo,
            time: this.collection.time,
            statistic: this.collection.statistic,
            tabName: this.tabName,
            items: this.filterNodes(statuses, this.collection.toJSON())
        };
    }

    filterNodes(statuses, nodes) {
        return nodes
            .map(item => this.mapNode(statuses, item))
            .filter(item => item.type === 'TestCaseNode' ? statuses[item.status] : item.children.length > 0)
            .sort((a, b) => a.name.localeCompare(b.name));
    }

    mapNode(statuses, node) {
        if (node.type === 'TestCaseNode') {
            return node;
        }
        return Object.assign({}, node, {
            children: this.filterNodes(statuses, node.children)
        });
    }
}

export default TreeView;
<|endoftext|>