<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.buying");

{% include 'erpnext/public/js/controllers/buying.js' %};

frappe.ui.form.on("Purchase Order", {
	setup: function(frm) {
		frm.custom_make_buttons = {
			'Purchase Receipt': 'Receipt',
			'Purchase Invoice': 'Invoice',
			'Stock Entry': 'Material to Supplier'
		}

		frm.set_query("reserve_warehouse", "supplied_items", function() {
			return {
				filters: {
					"company": frm.doc.company,
					"is_group": 0
				}
			}
		});

		frm.set_indicator_formatter('item_code',
			function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })

		frm.set_query("blanket_order", "items", function() {
			return {
				filters: {
					"docstatus": 1
				}
			}
		});
	},

	onload: function(frm) {
		set_schedule_date(frm);

		erpnext.queries.setup_queries(frm, "Warehouse", function() {
			return erpnext.queries.warehouse(frm.doc);
		});

		if (frm.doc.__onload) {
			frm.toggle_display('get_last_purchase_rate',
				frm.doc.__onload.disable_fetch_last_purchase_rate);
		}
	},
});

frappe.ui.form.on("Purchase Order Item", {
	schedule_date: function(frm, cdt, cdn) {
		var row = locals[cdt][cdn];
		if (row.schedule_date) {
			if(!frm.doc.schedule_date) {
				erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date");
			} else {
				set_schedule_date(frm);
			}
		}
	}
});

erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
	refresh: function(doc, cdt, cdn) {
		var me = this;
		this._super();
		var allow_receipt = false;
		var is_drop_ship = false;

		for (var i in cur_frm.doc.items) {
			var item = cur_frm.doc.items[i];
			if(item.delivered_by_supplier !== 1) {
				allow_receipt = true;
			} else {
				is_drop_ship = true;
			}

			if(is_drop_ship && allow_receipt) {
				break;
			}
		}

		cur_frm.set_df_property("drop_ship", "hidden", !is_drop_ship);

		if(doc.docstatus == 1 && !in_list(["Closed", "Delivered"], doc.status)) {
			if (this.frm.has_perm("submit")) {
				if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
					cur_frm.add_custom_button(__('Close'), this.close_purchase_order, __("Status"));
				}
			}

			if(is_drop_ship && doc.status!="Delivered"){
				cur_frm.add_custom_button(__('Delivered'),
					this.delivered_by_supplier, __("Status"));

				cur_frm.page.set_inner_btn_group_as_primary(__("Status"));
			}
		} else if(doc.docstatus===0) {
			cur_frm.cscript.add_from_mappers();
		}

		if(doc.docstatus == 1 && in_list(["Closed", "Delivered"], doc.status)) {
			if (this.frm.has_perm("submit")) {
				cur_frm.add_custom_button(__('Re-open'), this.unclose_purchase_order, __("Status"));
			}
		}

		if(doc.docstatus == 1 && doc.status != "Closed") {
			if(flt(doc.per_received, 2) < 100 && allow_receipt) {
				cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __("Make"));

				if(doc.is_subcontracted==="Yes") {
					cur_frm.add_custom_button(__('Material to Supplier'),
						function() { me.make_stock_entry(); }, __("Transfer"));
				}
			}

			if(flt(doc.per_billed, 2) < 100)
				cur_frm.add_custom_button(__('Invoice'),
					this.make_purchase_invoice, __("Make"));

			if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __("Make"));
			}

			if(!doc.auto_repeat) {
				cur_frm.add_custom_button(__('Subscription'), function() {
					erpnext.utils.make_subscription(doc.doctype, doc.name)
				}, __("Make"))
			}
			cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
		}
	},

	get_items_from_open_material_requests: function() {
		erpnext.utils.map_current_doc({
			method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
			source_name: this.frm.doc.supplier,
			get_query_filters: {
				docstatus: ["!=", 2],
			}
		});
	},

	validate: function() {
		set_schedule_date(this.frm);
	},

	make_stock_entry: function() {
		var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
		var me = this;

		if(items.length >= 1){
			me.raw_material_data = [];
			me.show_dialog = 1;
			let title = "";
			let fields = [
			{fieldtype:'Section Break', label: __('Raw Materials')},
			{fieldname: 'sub_con_rm_items', fieldtype: 'Table',
				fields: [
					{
						fieldtype:'Data',
						fieldname:'item_code',
						label: __('Item'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Data',
						fieldname:'rm_item_code',
						label: __('Raw Material'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'qty',
						label: __('Quantity'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Data',
						read_only:1,
						fieldname:'warehouse',
						label: __('Reserve Warehouse'),
						in_list_view:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'rate',
						label: __('Rate'),
						hidden:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'amount',
						label: __('Amount'),
						hidden:1
					},
					{
						fieldtype:'Link',
						read_only:1,
						fieldname:'uom',
						label: __('UOM'),
						hidden:1
					}
				],
				data: me.raw_material_data,
				get_data: function() {
					return me.raw_material_data;
				}
			}
		]

		me.dialog = new frappe.ui.Dialog({
			title: title, fields: fields
		});

		if (me.frm.doc['supplied_items']) {
			me.frm.doc['supplied_items'].forEach((item, index) => {
			if (item.rm_item_code && item.main_item_code) {
					me.raw_material_data.push ({
						'name':item.name,
						'item_code': item.main_item_code,
						'rm_item_code': item.rm_item_code,
						'item_name': item.rm_item_code,
						'qty': item.required_qty,
						'warehouse':item.reserve_warehouse,
						'rate':item.rate,
						'amount':item.amount,
						'stock_uom':item.stock_uom
					});
					me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
				}
			})
		}

		me.dialog.show()
		this.dialog.set_primary_action(__('Transfer'), function() {
			me.values = me.dialog.get_values();
			if(me.values) {
				me.values.sub_con_rm_items.map((row,i) => {
					if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
						frappe.throw(__("Item Code, warehouse, quantity are required on row" + (i+1)));
					}
				})
				me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
				me.dialog.hide()
				}
			});
		}

		me.dialog.get_close_btn().on('click', () => {
			me.dialog.hide();
		});

	},

	_make_rm_stock_entry: function(rm_items) {
		frappe.call({
			method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
			args: {
				purchase_order: cur_frm.doc.name,
				rm_items: rm_items
			}
			,
			callback: function(r) {
				var doclist = frappe.model.sync(r.message);
				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
			}
		});
	},

	make_purchase_receipt: function() {
		frappe.model.open_mapped_doc({
			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
			frm: cur_frm
		})
	},

	make_purchase_invoice: function() {
		frappe.model.open_mapped_doc({
			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
			frm: cur_frm
		})
	},

	add_from_mappers: function() {
		var me = this;
		this.frm.add_custom_button(__('Material Request'),
			function() {
				erpnext.utils.map_current_doc({
					method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
					source_doctype: "Material Request",
					target: me.frm,
					setters: {
						company: me.frm.doc.company
					},
					get_query_filters: {
						material_request_type: "Purchase",
						docstatus: 1,
						status: ["!=", "Stopped"],
						per_ordered: ["<", 99.99],
					}
				})
			}, __("Add items from"));

		this.frm.add_custom_button(__('Supplier Quotation'),
			function() {
				erpnext.utils.map_current_doc({
					method: "erpnext.buying.doctype.supplier_quotation.supplier_quotation.make_purchase_order",
					source_doctype: "Supplier Quotation",
					target: me.frm,
					setters: {
						company: me.frm.doc.company
					},
					get_query_filters: {
						docstatus: 1,
						status: ["!=", "Stopped"],
					}
				})
			}, __("Add items from"));

	},

	tc_name: function() {
		this.get_terms();
	},

	items_add: function(doc, cdt, cdn) {
		var row = frappe.get_doc(cdt, cdn);
		if(doc.schedule_date) {
			row.schedule_date = doc.schedule_date;
			refresh_field("schedule_date", cdn, "items");
		} else {
			this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
		}
	},

	unclose_purchase_order: function(){
		cur_frm.cscript.update_status('Re-open', 'Submitted')
	},

	close_purchase_order: function(){
		cur_frm.cscript.update_status('Close', 'Closed')
	},

	delivered_by_supplier: function(){
		cur_frm.cscript.update_status('Deliver', 'Delivered')
	},

	get_last_purchase_rate: function() {
		frappe.call({
			"method": "get_last_purchase_rate",
			"doc": cur_frm.doc,
			callback: function(r, rt) {
				cur_frm.dirty();
				cur_frm.cscript.calculate_taxes_and_totals();
			}
		})
	},

	items_on_form_rendered: function() {
		set_schedule_date(this.frm);
	},

	schedule_date: function() {
		set_schedule_date(this.frm);
	}
});

// for backward compatibility: combine new and previous states
$.extend(cur_frm.cscript, new erpnext.buying.PurchaseOrderController({frm: cur_frm}));

cur_frm.cscript.update_status= function(label, status){
	frappe.call({
		method: "erpnext.buying.doctype.purchase_order.purchase_order.update_status",
		args: {status: status, name: cur_frm.doc.name},
		callback: function(r) {
			cur_frm.set_value("status", status);
			cur_frm.reload_doc();
		}
	})
}

cur_frm.fields_dict['items'].grid.get_field('project').get_query = function(doc, cdt, cdn) {
	return {
		filters:[
			['Project', 'status', 'not in', 'Completed, Cancelled']
		]
	}
}

cur_frm.fields_dict['items'].grid.get_field('bom').get_query = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn]
	return {
		filters: [
			['BOM', 'item', '=', d.item_code],
			['BOM', 'is_active', '=', '1'],
			['BOM', 'docstatus', '=', '1'],
			['BOM', 'company', '=', doc.company]
		]
	}
}

function set_schedule_date(frm) {
	if(frm.doc.schedule_date){
		erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
	}
}

frappe.provide("erpnext.buying");

frappe.ui.form.on("Purchase Order", "is_subcontracted", function(frm) {
	if (frm.doc.is_subcontracted === "Yes") {
		erpnext.buying.get_default_bom(frm);
	}
});
<commit_msg>Update purchase_order.js<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.buying");

{% include 'erpnext/public/js/controllers/buying.js' %};

frappe.ui.form.on("Purchase Order", {
	setup: function(frm) {
		frm.custom_make_buttons = {
			'Purchase Receipt': 'Receipt',
			'Purchase Invoice': 'Invoice',
			'Stock Entry': 'Material to Supplier'
		}

		frm.set_query("reserve_warehouse", "supplied_items", function() {
			return {
				filters: {
					"company": frm.doc.company,
					"is_group": 0
				}
			}
		});

		frm.set_indicator_formatter('item_code',
			function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })

		frm.set_query("blanket_order", "items", function() {
			return {
				filters: {
					"company": frm.doc.company,
					"docstatus": 1
				}
			}
		});
	},

	onload: function(frm) {
		set_schedule_date(frm);

		erpnext.queries.setup_queries(frm, "Warehouse", function() {
			return erpnext.queries.warehouse(frm.doc);
		});

		if (frm.doc.__onload) {
			frm.toggle_display('get_last_purchase_rate',
				frm.doc.__onload.disable_fetch_last_purchase_rate);
		}
	},
});

frappe.ui.form.on("Purchase Order Item", {
	schedule_date: function(frm, cdt, cdn) {
		var row = locals[cdt][cdn];
		if (row.schedule_date) {
			if(!frm.doc.schedule_date) {
				erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date");
			} else {
				set_schedule_date(frm);
			}
		}
	}
});

erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
	refresh: function(doc, cdt, cdn) {
		var me = this;
		this._super();
		var allow_receipt = false;
		var is_drop_ship = false;

		for (var i in cur_frm.doc.items) {
			var item = cur_frm.doc.items[i];
			if(item.delivered_by_supplier !== 1) {
				allow_receipt = true;
			} else {
				is_drop_ship = true;
			}

			if(is_drop_ship && allow_receipt) {
				break;
			}
		}

		cur_frm.set_df_property("drop_ship", "hidden", !is_drop_ship);

		if(doc.docstatus == 1 && !in_list(["Closed", "Delivered"], doc.status)) {
			if (this.frm.has_perm("submit")) {
				if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
					cur_frm.add_custom_button(__('Close'), this.close_purchase_order, __("Status"));
				}
			}

			if(is_drop_ship && doc.status!="Delivered"){
				cur_frm.add_custom_button(__('Delivered'),
					this.delivered_by_supplier, __("Status"));

				cur_frm.page.set_inner_btn_group_as_primary(__("Status"));
			}
		} else if(doc.docstatus===0) {
			cur_frm.cscript.add_from_mappers();
		}

		if(doc.docstatus == 1 && in_list(["Closed", "Delivered"], doc.status)) {
			if (this.frm.has_perm("submit")) {
				cur_frm.add_custom_button(__('Re-open'), this.unclose_purchase_order, __("Status"));
			}
		}

		if(doc.docstatus == 1 && doc.status != "Closed") {
			if(flt(doc.per_received, 2) < 100 && allow_receipt) {
				cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __("Make"));

				if(doc.is_subcontracted==="Yes") {
					cur_frm.add_custom_button(__('Material to Supplier'),
						function() { me.make_stock_entry(); }, __("Transfer"));
				}
			}

			if(flt(doc.per_billed, 2) < 100)
				cur_frm.add_custom_button(__('Invoice'),
					this.make_purchase_invoice, __("Make"));

			if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __("Make"));
			}

			if(!doc.auto_repeat) {
				cur_frm.add_custom_button(__('Subscription'), function() {
					erpnext.utils.make_subscription(doc.doctype, doc.name)
				}, __("Make"))
			}
			cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
		}
	},

	get_items_from_open_material_requests: function() {
		erpnext.utils.map_current_doc({
			method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
			source_name: this.frm.doc.supplier,
			get_query_filters: {
				docstatus: ["!=", 2],
			}
		});
	},

	validate: function() {
		set_schedule_date(this.frm);
	},

	make_stock_entry: function() {
		var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
		var me = this;

		if(items.length >= 1){
			me.raw_material_data = [];
			me.show_dialog = 1;
			let title = "";
			let fields = [
			{fieldtype:'Section Break', label: __('Raw Materials')},
			{fieldname: 'sub_con_rm_items', fieldtype: 'Table',
				fields: [
					{
						fieldtype:'Data',
						fieldname:'item_code',
						label: __('Item'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Data',
						fieldname:'rm_item_code',
						label: __('Raw Material'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'qty',
						label: __('Quantity'),
						read_only:1,
						in_list_view:1
					},
					{
						fieldtype:'Data',
						read_only:1,
						fieldname:'warehouse',
						label: __('Reserve Warehouse'),
						in_list_view:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'rate',
						label: __('Rate'),
						hidden:1
					},
					{
						fieldtype:'Float',
						read_only:1,
						fieldname:'amount',
						label: __('Amount'),
						hidden:1
					},
					{
						fieldtype:'Link',
						read_only:1,
						fieldname:'uom',
						label: __('UOM'),
						hidden:1
					}
				],
				data: me.raw_material_data,
				get_data: function() {
					return me.raw_material_data;
				}
			}
		]

		me.dialog = new frappe.ui.Dialog({
			title: title, fields: fields
		});

		if (me.frm.doc['supplied_items']) {
			me.frm.doc['supplied_items'].forEach((item, index) => {
			if (item.rm_item_code && item.main_item_code) {
					me.raw_material_data.push ({
						'name':item.name,
						'item_code': item.main_item_code,
						'rm_item_code': item.rm_item_code,
						'item_name': item.rm_item_code,
						'qty': item.required_qty,
						'warehouse':item.reserve_warehouse,
						'rate':item.rate,
						'amount':item.amount,
						'stock_uom':item.stock_uom
					});
					me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
				}
			})
		}

		me.dialog.show()
		this.dialog.set_primary_action(__('Transfer'), function() {
			me.values = me.dialog.get_values();
			if(me.values) {
				me.values.sub_con_rm_items.map((row,i) => {
					if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
						frappe.throw(__("Item Code, warehouse, quantity are required on row" + (i+1)));
					}
				})
				me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
				me.dialog.hide()
				}
			});
		}

		me.dialog.get_close_btn().on('click', () => {
			me.dialog.hide();
		});

	},

	_make_rm_stock_entry: function(rm_items) {
		frappe.call({
			method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
			args: {
				purchase_order: cur_frm.doc.name,
				rm_items: rm_items
			}
			,
			callback: function(r) {
				var doclist = frappe.model.sync(r.message);
				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
			}
		});
	},

	make_purchase_receipt: function() {
		frappe.model.open_mapped_doc({
			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
			frm: cur_frm
		})
	},

	make_purchase_invoice: function() {
		frappe.model.open_mapped_doc({
			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
			frm: cur_frm
		})
	},

	add_from_mappers: function() {
		var me = this;
		this.frm.add_custom_button(__('Material Request'),
			function() {
				erpnext.utils.map_current_doc({
					method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
					source_doctype: "Material Request",
					target: me.frm,
					setters: {
						company: me.frm.doc.company
					},
					get_query_filters: {
						material_request_type: "Purchase",
						docstatus: 1,
						status: ["!=", "Stopped"],
						per_ordered: ["<", 99.99],
					}
				})
			}, __("Add items from"));

		this.frm.add_custom_button(__('Supplier Quotation'),
			function() {
				erpnext.utils.map_current_doc({
					method: "erpnext.buying.doctype.supplier_quotation.supplier_quotation.make_purchase_order",
					source_doctype: "Supplier Quotation",
					target: me.frm,
					setters: {
						company: me.frm.doc.company
					},
					get_query_filters: {
						docstatus: 1,
						status: ["!=", "Stopped"],
					}
				})
			}, __("Add items from"));

	},

	tc_name: function() {
		this.get_terms();
	},

	items_add: function(doc, cdt, cdn) {
		var row = frappe.get_doc(cdt, cdn);
		if(doc.schedule_date) {
			row.schedule_date = doc.schedule_date;
			refresh_field("schedule_date", cdn, "items");
		} else {
			this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
		}
	},

	unclose_purchase_order: function(){
		cur_frm.cscript.update_status('Re-open', 'Submitted')
	},

	close_purchase_order: function(){
		cur_frm.cscript.update_status('Close', 'Closed')
	},

	delivered_by_supplier: function(){
		cur_frm.cscript.update_status('Deliver', 'Delivered')
	},

	get_last_purchase_rate: function() {
		frappe.call({
			"method": "get_last_purchase_rate",
			"doc": cur_frm.doc,
			callback: function(r, rt) {
				cur_frm.dirty();
				cur_frm.cscript.calculate_taxes_and_totals();
			}
		})
	},

	items_on_form_rendered: function() {
		set_schedule_date(this.frm);
	},

	schedule_date: function() {
		set_schedule_date(this.frm);
	}
});

// for backward compatibility: combine new and previous states
$.extend(cur_frm.cscript, new erpnext.buying.PurchaseOrderController({frm: cur_frm}));

cur_frm.cscript.update_status= function(label, status){
	frappe.call({
		method: "erpnext.buying.doctype.purchase_order.purchase_order.update_status",
		args: {status: status, name: cur_frm.doc.name},
		callback: function(r) {
			cur_frm.set_value("status", status);
			cur_frm.reload_doc();
		}
	})
}

cur_frm.fields_dict['items'].grid.get_field('project').get_query = function(doc, cdt, cdn) {
	return {
		filters:[
			['Project', 'status', 'not in', 'Completed, Cancelled']
		]
	}
}

cur_frm.fields_dict['items'].grid.get_field('bom').get_query = function(doc, cdt, cdn) {
	var d = locals[cdt][cdn]
	return {
		filters: [
			['BOM', 'item', '=', d.item_code],
			['BOM', 'is_active', '=', '1'],
			['BOM', 'docstatus', '=', '1'],
			['BOM', 'company', '=', doc.company]
		]
	}
}

function set_schedule_date(frm) {
	if(frm.doc.schedule_date){
		erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
	}
}

frappe.provide("erpnext.buying");

frappe.ui.form.on("Purchase Order", "is_subcontracted", function(frm) {
	if (frm.doc.is_subcontracted === "Yes") {
		erpnext.buying.get_default_bom(frm);
	}
});
<|endoftext|>


<commit_before>/*
 * jquery.multisortable.js
 * https://github.com/iamvery/jquery.multisortable
 *
 * Author: Ethan Atlakson, Jay Hayes
 * Last Revision 3/16/2012
 * multi-selectable, multi-sortable jQuery plugin
 * jquery.multisortable.js
 * v0.1.1
*/

jQuery.fn.multiselectable = function(options) {
	if (!options) { options = {}; }
	options = jQuery.extend({}, jQuery.fn.multiselectable.defaults, options);

	return this.each(function() {
		var t = jQuery(this);

		if (!jQuery(t.children()).data('multiselectable')) {
			jQuery(t.children()).data('multiselectable', true);
			jQuery(t.children()).click(function(e) {
				var parent = jQuery(this).parent();
				var myIndex = jQuery(parent.children()).index(jQuery(this));
				var prevIndex = jQuery(parent.children()).index(jQuery('.multiselectable-previous', parent));

				if (!e.ctrlKey && !e.metaKey) {
					jQuery('.' + options.selectedClass, parent).removeClass(options.selectedClass);
				} else {
					if (jQuery(this).not('.child').length) {
						if (jQuery(this).hasClass(options.selectedClass))
							jQuery(this).nextUntil(':not(.child)').removeClass(options.selectedClass);
						else
							jQuery(this).nextUntil(':not(.child)').addClass(options.selectedClass);
					}
				}

				if (e.shiftKey && prevIndex >= 0) {
					jQuery('.multiselectable-previous', parent).toggleClass(options.selectedClass);
					if (prevIndex < myIndex) {
						jQuery(this).prevUntil('.multiselectable-previous').toggleClass(options.selectedClass);
					} else if (prevIndex > myIndex) {
						jQuery(this).nextUntil('.multiselectable-previous').toggleClass(options.selectedClass);
					}
				}

				jQuery(this).toggleClass(options.selectedClass);
				jQuery('.multiselectable-previous', parent).removeClass('multiselectable-previous');
				jQuery(this).addClass('multiselectable-previous');
				options.click(e, $(this));
			}).disableSelection();
		}
	});
};

jQuery.fn.multiselectable.defaults = {
	click: function(event, elem){},
	selectedClass: 'selected'
};

jQuery.fn.multisortable = function(options) {
	if (!options) { options = {}; }
	settings = jQuery.extend({}, jQuery.fn.multisortable.defaults, options);

	function regroup(item, list) {
		if (jQuery('.' + settings.selectedClass, list).length > 0) {
			var myIndex = item.data('i');

			var itemsBefore = jQuery('.' + settings.selectedClass, list).filter(function() {
													return jQuery(this).data('i') < myIndex;
												}).css('position', '').css('width', '');
			item.before(itemsBefore);

			var itemsAfter =	jQuery('.' + settings.selectedClass, list).filter(function() {
													return jQuery(this).data('i') > myIndex;
												}).css('position', '').css('width', '');
			item.after(itemsAfter);

			setTimeout(function(){
				itemsAfter.add(itemsBefore).addClass(settings.selectedClass);
			}, 0);
		}
	}

	return this.each(function() {
		var t = jQuery(this);
		var tagName = t.children().get(0).tagName;

		//enable multi-selection
		t.multiselectable({selectedClass: settings.selectedClass, click: settings.click});

		//enable sorting
		options.cancel = tagName+':not(.'+settings.selectedClass+')';
		options.placeholder = settings.placeholder;
		options.start = function(event, ui) {
			if (ui.item.hasClass(settings.selectedClass)) {
				var parent = ui.item.parent();

				//assign indexes to all selected items
				jQuery('.' + settings.selectedClass, parent).each(function(i) {
					jQuery(this).data('i', i)
				});

				// adjust placeholder size to be size of items
				var height = jQuery('.' + settings.selectedClass, parent).length * ui.item.outerHeight();
				ui.placeholder.height(height);
			}

			settings.start(event, ui);
		};

		options.stop = function(event, ui) {
			regroup(ui.item, ui.item.parent());
			settings.stop(event, ui);
		};

		options.sort = function(event, ui) {
			var parent = ui.item.parent();
			var myIndex = ui.item.data('i');
			var top = parseInt(ui.item.css('top').replace('px', ''));
			var left = parseInt(ui.item.css('left').replace('px', ''));

			jQuery.fn.reverse = Array.prototype.reverse;
			var h = 0;
			jQuery('.' + settings.selectedClass, parent).filter(function() {
				return jQuery(this).data('i') < myIndex;
			}).reverse().each(function() {
				h += jQuery(this).outerHeight();
				jQuery(this).css({
					left: left,
					top: top - h,
					position: 'absolute',
					zIndex: 1000,
					width: ui.item.width()
				});
			});

			var h = ui.item.outerHeight();
			jQuery('.' + settings.selectedClass, parent).filter(function() {
				return jQuery(this).data('i') > myIndex;
			}).each(function() {
				jQuery(this).css({
					left: left,
					top: top + h,
					position: 'absolute',
					zIndex: 1000,
					width: ui.item.width()
				});

				h += jQuery(this).outerHeight();
			});

			settings.sort(event, ui);
		};

		options.receive = function(event, ui) {
			regroup(ui.item, ui.sender);
			settings.receive(event, ui);
		};

		jQuery(t).sortable(options).disableSelection();
	});
};

jQuery.fn.multisortable.defaults = {
	start: function(event, ui) { },
	stop: function(event, ui) { },
	sort: function(event, ui) { },
	receive: function(event, ui) { },
	click: function(event, elem) { },
	selectedClass: 'selected',
	placeholder: 'placeholder'
};
<commit_msg>Refactored to more my style... and passing tests! :)<commit_after>/*
 * jquery.multisortable.js - v0.1.1
 * https://github.com/iamvery/jquery.multisortable
 *
 * Author: Ethan Atlakson, Jay Hayes
 * Last Revision 3/16/2012
 * multi-selectable, multi-sortable jQuery plugin
*/

!function($){

	$.fn.multiselectable = function(options) {
		if (!options) { options = {} }
		options = $.extend({}, $.fn.multiselectable.defaults, options)

		return this.each(function() {
			var list = $(this)

			if (!list.children().data('multiselectable')) {
				list.children().data('multiselectable', true)
				list.children().click(function(e) {
					var item = $(this),
						parent = item.parent(),
						myIndex = parent.children().index(item),
						prevIndex = parent.children().index(parent.find('.multiselectable-previous'))

					if (!e.ctrlKey && !e.metaKey)
						parent.find('.' + options.selectedClass).removeClass(options.selectedClass)
					else {
						if (item.not('.child').length) {
							if (item.hasClass(options.selectedClass))
								item.nextUntil(':not(.child)').removeClass(options.selectedClass)
							else
								item.nextUntil(':not(.child)').addClass(options.selectedClass)
						}
					}

					if (e.shiftKey && prevIndex >= 0) {
						parent.find('.multiselectable-previous').toggleClass(options.selectedClass)
						if (prevIndex < myIndex)
							item.prevUntil('.multiselectable-previous').toggleClass(options.selectedClass)
						else if (prevIndex > myIndex)
							item.nextUntil('.multiselectable-previous').toggleClass(options.selectedClass)
					}

					item.toggleClass(options.selectedClass)
					parent.find('.multiselectable-previous').removeClass('multiselectable-previous')
					item.addClass('multiselectable-previous')

					options.click(e, item)
				}).disableSelection()
			}
		})
	}

	$.fn.multiselectable.defaults = {
		click: function(event, elem){},
		selectedClass: 'selected'
	}

	$.fn.multisortable = function(options) {
		if (!options) { options = {} }
		settings = $.extend({}, $.fn.multisortable.defaults, options)

		function regroup(item, list) {
			if (list.find('.' + settings.selectedClass).length > 0) {
				var myIndex = item.data('i')

				var itemsBefore = list.find('.' + settings.selectedClass).filter(function() {
					return $(this).data('i') < myIndex
				}).css({
					position: '',
					width: ''
				})

				item.before(itemsBefore)

				var itemsAfter = list.find('.' + settings.selectedClass).filter(function() {
					return $(this).data('i') > myIndex
				}).css({
					position: '',
					width: ''
				})

				item.after(itemsAfter)

				setTimeout(function(){
					itemsAfter.add(itemsBefore).addClass(settings.selectedClass)
				}, 0)
			}
		}

		return this.each(function() {
			var list = $(this)
			var tagName = list.children().get(0).tagName

			//enable multi-selection
			list.multiselectable({selectedClass: settings.selectedClass, click: settings.click})

			//enable sorting
			options.cancel = tagName+':not(.'+settings.selectedClass+')'
			options.placeholder = settings.placeholder
			options.start = function(event, ui) {
				if (ui.item.hasClass(settings.selectedClass)) {
					var parent = ui.item.parent()

					//assign indexes to all selected items
					parent.find('.' + settings.selectedClass).each(function(i) {
						$(this).data('i', i)
					})

					// adjust placeholder size to be size of items
					var height = parent.find('.' + settings.selectedClass).length * ui.item.outerHeight()
					ui.placeholder.height(height)
				}

				settings.start(event, ui)
			}

			options.stop = function(event, ui) {
				regroup(ui.item, ui.item.parent())
				settings.stop(event, ui)
			}

			options.sort = function(event, ui) {
				var parent = ui.item.parent(),
					myIndex = ui.item.data('i'),
					top = parseInt(ui.item.css('top').replace('px', '')),
					left = parseInt(ui.item.css('left').replace('px', ''))

				$.fn.reverse = Array.prototype.reverse
				var height = 0
				$('.' + settings.selectedClass, parent).filter(function() {
					return $(this).data('i') < myIndex
				}).reverse().each(function() {
					height += $(this).outerHeight()
					$(this).css({
						left: left,
						top: top - height,
						position: 'absolute',
						zIndex: 1000,
						width: ui.item.width()
					})
				})

				var height = ui.item.outerHeight()
				$('.' + settings.selectedClass, parent).filter(function() {
					return $(this).data('i') > myIndex
				}).each(function() {
					var item = $(this)
					item.css({
						left: left,
						top: top + height,
						position: 'absolute',
						zIndex: 1000,
						width: ui.item.width()
					})

					height += item.outerHeight()
				})

				settings.sort(event, ui)
			}

			options.receive = function(event, ui) {
				regroup(ui.item, ui.sender)
				settings.receive(event, ui)
			}

			list.sortable(options).disableSelection()
		})
	}

	$.fn.multisortable.defaults = {
		start: function(event, ui) { },
		stop: function(event, ui) { },
		sort: function(event, ui) { },
		receive: function(event, ui) { },
		click: function(event, elem) { },
		selectedClass: 'selected',
		placeholder: 'placeholder'
	}

}(jQuery);
<|endoftext|>


<commit_before>const axios = require('axios');
const config = require('config');

const activitiesLib = require('../lib/activities');
const slackLib = require('./slack');
const activityType = require('../constants/activities');

module.exports = (Sequelize, activity) => {
  // publish everything to our private channel
  return publishToSlackPrivateChannel(activity)
    // publish a filtered version to our public channel
    .then(() => publishToSlack(activity, config.slack.webhookUrl,
      {
        channel: config.slack.publicActivityChannel
      }))
    // process notification entries
    .then(() => {
      if(!activity.GroupId || !activity.type) {
        return Promise.resolve([]);
      }
      return Sequelize.models.Notification.findAll({
        where: {
          type: [
            activityType.ACTIVITY_ALL,
            activity.type
          ],
          GroupId: activity.GroupId,
          // for now, only handle gitter and slack webhooks in this lib
          // TODO sdubois: move email + internal slack channels to this lib
          channel: ['gitter', 'slack'],
          active: true
        }
      })
    })
    .then(notifConfigs =>
      Promise.all(notifConfigs, notifConfig => {
        if (notifConfig.channel === 'gitter') {
          return publishToGitter(activity, notifConfig);
        } else if (notifConfig.channel === 'slack') {
          return publishToSlack(activity, notifConfig.webhookUrl, {});
        } else {
          return Promise.resolve();
        }
      }))
    .catch(err => {
      console.error(`Error while publishing activity type ${activity.type} for group ${activity.GroupId}`, err);
    });
};

function publishToGitter(activity, notifConfig) {
  const message = activitiesLib.formatMessageForPublicChannel(activity, false);

  if (message) {
    return axios.post(notifConfig.webhookUrl, { message });
  } else {
    Promise.resolve();
  }
}

function publishToSlack(activity, webhookUrl, options) {
  return slackLib.postActivityOnPublicChannel(activity, webhookUrl, options);
}

function publishToSlackPrivateChannel(activity) {
  return slackLib.postActivityOnPrivateChannel(activity);
}<commit_msg>fix for gitter integration<commit_after>const axios = require('axios');
const config = require('config');
const Promise = require('bluebird');

const activitiesLib = require('../lib/activities');
const slackLib = require('./slack');
const activityType = require('../constants/activities');

module.exports = (Sequelize, activity) => {
  // publish everything to our private channel
  return publishToSlackPrivateChannel(activity)
    // publish a filtered version to our public channel
    .then(() => publishToSlack(activity, config.slack.webhookUrl,
      {
        channel: config.slack.publicActivityChannel
      }))
    // process notification entries
    .then(() => {
      if(!activity.GroupId || !activity.type) {
        return Promise.resolve([]);
      }
      return Sequelize.models.Notification.findAll({
        where: {
          type: [
            activityType.ACTIVITY_ALL,
            activity.type
          ],
          GroupId: activity.GroupId,
          // for now, only handle gitter and slack webhooks in this lib
          // TODO sdubois: move email + internal slack channels to this lib
          channel: ['gitter', 'slack'],
          active: true
        }
      })
    })
    .then(notifConfigs =>
      Promise.map(notifConfigs, notifConfig => {
        if (notifConfig.channel === 'gitter') {
          return publishToGitter(activity, notifConfig);
        } else if (notifConfig.channel === 'slack') {
          return publishToSlack(activity, notifConfig.webhookUrl, {});
        } else {
          return Promise.resolve();
        }
      }))
    .catch(err => {
      console.error(`Error while publishing activity type ${activity.type} for group ${activity.GroupId}`, err);
    });
};

function publishToGitter(activity, notifConfig) {
  const message = activitiesLib.formatMessageForPublicChannel(activity, false);
  if (message) {
    return axios.post(notifConfig.webhookUrl, { message });
  } else {
    Promise.resolve();
  }
}

function publishToSlack(activity, webhookUrl, options) {
  return slackLib.postActivityOnPublicChannel(activity, webhookUrl, options);
}

function publishToSlackPrivateChannel(activity) {
  return slackLib.postActivityOnPrivateChannel(activity);
}<|endoftext|>


<commit_before>'use strict';

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
  return Promise.all([getChannelURL('release'), getChannelURL('beta'), getChannelURL('canary')]).then(urls => {
    return {
      useYarn: true,
      scenarios: [
        {
          name: 'with-max-transpilation',
          env: {
            TARGET_IE11: true,
          },
          npm: {},
        },
        {
          name: 'with-ember-fetch-no-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': false }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': '^8.0.2',
              '@ember/jquery': null,
            },
          },
        },
        {
          name: 'with-ember-fetch-and-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': '^6.5.1',
              '@ember/jquery': '^1.1.0',
            },
          },
        },
        {
          name: 'with-native-fetch',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': false }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': null,
              '@ember/jquery': null,
            },
          },
        },
        {
          name: 'with-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': null,
              '@ember/jquery': '^1.1.0',
            },
          },
        },
        {
          name: 'ember-lts-3.12',
          npm: {
            devDependencies: {
              'ember-source': '~3.12.0',
            },
          },
        },
        {
          name: 'ember-lts-3.16',
          npm: {
            devDependencies: {
              'ember-source': '~3.16.0',
            },
          },
        },
        {
          name: 'ember-release',
          npm: {
            devDependencies: {
              'ember-source': urls[0],
            },
          },
        },
        {
          name: 'ember-beta',
          npm: {
            devDependencies: {
              'ember-source': urls[1],
            },
          },
        },
        {
          name: 'ember-canary',
          npm: {
            devDependencies: {
              'ember-source': urls[2],
            },
          },
        },
      ],
    };
  });
};
<commit_msg>update ember-fetch-and-jquery<commit_after>'use strict';

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
  return Promise.all([getChannelURL('release'), getChannelURL('beta'), getChannelURL('canary')]).then(urls => {
    return {
      useYarn: true,
      scenarios: [
        {
          name: 'with-max-transpilation',
          env: {
            TARGET_IE11: true,
          },
          npm: {},
        },
        {
          name: 'with-ember-fetch-no-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': false }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': '^8.0.2',
              '@ember/jquery': null,
            },
          },
        },
        {
          name: 'with-ember-fetch-and-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': '^8.0.2',
              '@ember/jquery': '^1.1.0',
            },
          },
        },
        {
          name: 'with-native-fetch',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': false }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': null,
              '@ember/jquery': null,
            },
          },
        },
        {
          name: 'with-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }),
          },
          npm: {
            devDependencies: {
              'ember-fetch': null,
              '@ember/jquery': '^1.1.0',
            },
          },
        },
        {
          name: 'ember-lts-3.12',
          npm: {
            devDependencies: {
              'ember-source': '~3.12.0',
            },
          },
        },
        {
          name: 'ember-lts-3.16',
          npm: {
            devDependencies: {
              'ember-source': '~3.16.0',
            },
          },
        },
        {
          name: 'ember-release',
          npm: {
            devDependencies: {
              'ember-source': urls[0],
            },
          },
        },
        {
          name: 'ember-beta',
          npm: {
            devDependencies: {
              'ember-source': urls[1],
            },
          },
        },
        {
          name: 'ember-canary',
          npm: {
            devDependencies: {
              'ember-source': urls[2],
            },
          },
        },
      ],
    };
  });
};
<|endoftext|>


<commit_before>'use strict';

// ## Module Dependencies
var _ = require('lodash');
var User = require('./neo4j/user.js');
var Architect = require('neo4j-architect');
var colog = require('colog');

Architect.init();

var Construct = Architect.Construct;
var Cypher = Architect.Cypher;

// ## Results Functions
// To be combined with queries using _.partial()

// return a single user
var _singleUser = function (results, callback) {
  if (results.length) {
    callback(null, new User(results[0].user));
  } else {
    callback(null, null);
  }
};

// return many users
var _manyUsers = function (results, callback) {
  var users = _.map(results, function (result) {
    return new User(result.user);
  });

  callback(null, users);
};

// ## Query Functions
// Should be combined with results functions using _.partial()

var _matchBy = function (keys, params, callback) {
  var cypherParams = _.pick(params, keys);

  var query = [
    'MATCH (user:User)',
    Cypher.where('user', keys),
    'RETURN user'
  ].join('\n');

  colog.info(query);

  callback(null, query, cypherParams);
};

var _matchByUUID = _.partial(_matchBy, ['id']);

var _matchAll = _.partial(_matchBy, []);

// creates the user with cypher
var _create = function (params, callback) {
  colog.info(params);
  var cypherParams = {
    id : params.id,
    firstname : params.firstname,
    lastname : params.lastname,
    profileImage : params.profileImage,
  };

  var query = [

    'MERGE (user:User{id: {id}})',
    'ON CREATE',
    'SET user.created = timestamp(),',
      'user.firstname ={firstname},',
      'user.lastname: {lastname}',
      'user.profileImage = {profileImage}',
    'ON MATCH',
      'SET user.firstname ={firstname},',
      'user.lastname: {lastname}',
      'user.profileImage = {profileImage}',
    'SET user.lastLogin = timestamp()',
    'RETURN user'
  ].join('\n');

  colog.info(query);

  callback(null, query, cypherParams);
};

// update the user with cypher
// var _update = function (params, callback) {

//   var cypherParams = {
//     id : params.id,
//     firstname : params.firstname,
//     lastname : params.lastname,
//   };

//   var query = [
//     'MATCH (user:User {id:{id}})',
//     'SET user.firstname = {firstname}',
//     'SET user.lastname = {lastname}',
//     'RETURN user'
//   ].join('\n');

//   callback(null, query, cypherParams);
// };

// delete the user and any relationships with cypher
var _delete = function (params, callback) {
  var cypherParams = {
    id: params.id
  };

  var query = [
    'MATCH (user:User {id:{id}})',
    'OPTIONAL MATCH (user)-[r]-()',
    'DELETE user, r',
  ].join('\n');

  callback(null, query, cypherParams);
};

// delete all users
var _deleteAll = function (params, callback) {
  var cypherParams = {};

  var query = [
    'MATCH (user:User)',
    'OPTIONAL MATCH (user)-[r]-()',
    'DELETE user, r',
  ].join('\n');

  callback(null, query, cypherParams);
};

// create a new user

var getById = new Construct(_matchByUUID).query().then(_singleUser);

var getAll = new Construct(_matchAll, _manyUsers);

var create = new Construct(_create, _singleUser);
// get a user by id and update their properties
// var update = new Construct(_update, _singleUser);

// delete a user by id
var deleteUser = new Construct(_delete);

// delete a user by id
var deleteAllUsers = new Construct(_deleteAll);

// export exposed functions
module.exports = {
  getById: getById.done(),
  create: create.done(),
  getAll: getAll.done(),
  deleteUser: deleteUser.done(),
  deleteAllUsers: deleteAllUsers.done(),
};
<commit_msg>Changed console.log to colog.info<commit_after>'use strict';

// ## Module Dependencies
var _ = require('lodash');
var User = require('./neo4j/user.js');
var Architect = require('neo4j-architect');
var colog = require('colog');

Architect.init();

var Construct = Architect.Construct;
var Cypher = Architect.Cypher;

// ## Results Functions
// To be combined with queries using _.partial()

// return a single user
var _singleUser = function (results, callback) {
  if (results.length) {
    callback(null, new User(results[0].user));
  } else {
    callback(null, null);
  }
};

// return many users
var _manyUsers = function (results, callback) {
  var users = _.map(results, function (result) {
    return new User(result.user);
  });

  callback(null, users);
};

// ## Query Functions
// Should be combined with results functions using _.partial()

var _matchBy = function (keys, params, callback) {
  var cypherParams = _.pick(params, keys);

  var query = [
    'MATCH (user:User)',
    Cypher.where('user', keys),
    'RETURN user'
  ].join('\n');

  colog.info(query);

  callback(null, query, cypherParams);
};

var _matchByUUID = _.partial(_matchBy, ['id']);

var _matchAll = _.partial(_matchBy, []);

// creates the user with cypher
var _create = function (params, callback) {
  colog.info(params);
  var cypherParams = {
    id : params.id,
    firstname : params.firstname,
    lastname : params.lastname,
    profileImage : params.profileImage,
  };

  var query = [

    'MERGE (user:User{id: {id}})',
    'ON CREATE',
      'SET user.created = timestamp()',
    'SET user.lastLogin = timestamp()'
  ];

  if (cypherParams.firstname){
    query.push(
    'SET user.firstname ={firstname}');
  }
  if (cypherParams.lastname){
    query.push(
    'SET user.lastname= {lastname}');
  }
  if (cypherParams.profileImage){
    query.push(
    'SET user.profileImage = {profileImage}');
  }
  query.push(
    'RETURN user');

  query = query.join('\n');

  colog.info(query);

  callback(null, query, cypherParams);
};

// delete the user and any relationships with cypher
var _delete = function (params, callback) {
  var cypherParams = {
    id: params.id
  };

  var query = [
    'MATCH (user:User {id:{id}})',
    'OPTIONAL MATCH (user)-[r]-()',
    'DELETE user, r',
  ].join('\n');

  callback(null, query, cypherParams);
};

// delete all users
var _deleteAll = function (params, callback) {
  var cypherParams = {};

  var query = [
    'MATCH (user:User)',
    'OPTIONAL MATCH (user)-[r]-()',
    'DELETE user, r',
  ].join('\n');

  callback(null, query, cypherParams);
};

// create a new user

var getById = new Construct(_matchByUUID).query().then(_singleUser);

var getAll = new Construct(_matchAll, _manyUsers);

var create = new Construct(_create, _singleUser);
// get a user by id and update their properties
// var update = new Construct(_update, _singleUser);

// delete a user by id
var deleteUser = new Construct(_delete);

// delete a user by id
var deleteAllUsers = new Construct(_deleteAll);

// export exposed functions
module.exports = {
  getById: getById.done(),
  create: create.done(),
  getAll: getAll.done(),
  deleteUser: deleteUser.done(),
  deleteAllUsers: deleteAllUsers.done(),
};
<|endoftext|>


<commit_before>'use strict';

var crypto    = require('crypto');
var Express   = require('express');
var HttpError = require('synapse-common/http/error');
var Q         = require('q');
var qs        = require('querystring');
var request   = require('request');
var url       = require('url');
var _         = require('lodash');

var config = require('../config');

var options = {
    baseUrl        : 'http://' + config.frontend.host,
    callbackUri    : '/gh-callback',
    ghClientId     : config.github.clientId,
    ghClientSecret : config.github.clientSecret,
    ghLoginUrl     : 'https://github.com/login',
    scope          : 'gist'
};

var github = new Express();

function createState() {
    return crypto.randomBytes(8).toString('hex');
}

function authorizeUrl(state) {
    var query = {
        client_id    : options.ghClientId,
        redirect_uri : url.resolve(options.baseUrl, options.callbackUri),
        state        : state
    };

    if (options.scope) {
        query.scope = options.scope;
    }

    query = qs.stringify(query);

    return (options.ghLoginUrl + '/oauth/authorize?' + query);
}

function makeRequest(query) {
    return new Q.Promise(
        function (resolve, reject) {
            request(
                {
                    url  : options.ghLoginUrl + '/oauth/access_token',
                    qs   : query,
                    json : true
                },
                function (error, response, token) {
                    if (error) {
                        reject(new HttpError(token, response));
                    } else {
                        resolve(token);
                    }
                }
            );
        }
    );
}

github.get('/gh-login/?', function (req, res) {
    req.session.ghState = createState();

    res.redirect(302, authorizeUrl(req.session.state));
    res.end();
});

github.get('/gh-callback/?', function (req, res) {
    if (! req.query.code || ! req.session.ghState) {
        res.redirect(302, '/login');
        res.end();
    } else {
        var query = {
            client_id     : options.ghClientId,
            client_secret : options.ghClientSecret,
            code          : req.query.code,
            state         : req.session.state
        };

        makeRequest(query)
            .then(
                function (token) {
                    var redirectUrl = req.session.redirectUrl || '/';
                    req.session.ghState     = null;
                    req.session.ghToken     = token;
                    req.session.redirectUrl = null;
                    res.redirect(302, redirectUrl);
                    res.end();
                },
                function (error) {
                    console.error('There was a login error', error);
                    res.redirect(403, '/');
                    res.end();
                }
            )
            .done();
    }
});

module.exports = github;
<commit_msg>Trying this<commit_after>'use strict';

var crypto    = require('crypto');
var Express   = require('express');
var HttpError = require('synapse-common/http/error');
var Q         = require('q');
var qs        = require('querystring');
var request   = require('request');
var url       = require('url');
var _         = require('lodash');

var config = require('../config');

var options = {
    callbackUri    : 'http://' + config.frontend.host + '/gh-callback',
    ghClientId     : config.github.clientId,
    ghClientSecret : config.github.clientSecret,
    ghLoginUrl     : 'https://github.com/login',
    scope          : 'gist'
};

var github = new Express();

function createState() {
    return crypto.randomBytes(8).toString('hex');
}

function authorizeUrl(state) {
    var query = {
        client_id    : options.ghClientId,
        redirect_uri : options.callbackUri,
        state        : state
    };

    if (options.scope) {
        query.scope = options.scope;
    }

    query = qs.stringify(query);

    return (options.ghLoginUrl + '/oauth/authorize?' + query);
}

function makeRequest(query) {
    return new Q.Promise(
        function (resolve, reject) {
            request(
                {
                    url  : options.ghLoginUrl + '/oauth/access_token',
                    qs   : query,
                    json : true
                },
                function (error, response, token) {
                    if (error) {
                        reject(new HttpError(token, response));
                    } else {
                        resolve(token);
                    }
                }
            );
        }
    );
}

github.get('/gh-login/?', function (req, res) {
    req.session.ghState = createState();

    res.redirect(302, authorizeUrl(req.session.state));
    res.end();
});

github.get('/gh-callback/?', function (req, res) {
    if (! req.query.code || ! req.session.ghState) {
        res.redirect(302, '/login');
        res.end();
    } else {
        var query = {
            client_id     : options.ghClientId,
            client_secret : options.ghClientSecret,
            code          : req.query.code,
            state         : req.session.state
        };

        makeRequest(query)
            .then(
                function (token) {
                    var redirectUrl = req.session.redirectUrl || '/';
                    req.session.ghState     = null;
                    req.session.ghToken     = token;
                    req.session.redirectUrl = null;
                    res.redirect(302, redirectUrl);
                    res.end();
                },
                function (error) {
                    console.error('There was a login error', error);
                    res.redirect(403, '/');
                    res.end();
                }
            )
            .done();
    }
});

module.exports = github;
<|endoftext|>


<commit_before>Model[OBJECT] = function ObjectModel(def){

	var model = function(obj) {
		if(!(this instanceof model)){
			return new model(obj);
		}
		merge(this, obj, true);
		var proxy = getProxy(model, this, model[DEFINITION]);
		model[VALIDATE](proxy);
		return proxy;
	};

	setConstructorProto(model, O[PROTO]);
	initModel(model, def, Model[OBJECT]);
	return model;
};

setConstructorProto(Model[OBJECT], ModelProto);
var ObjectModelProto = Model[OBJECT][PROTO];

ObjectModelProto[DEFAULTS] = function(p){
	merge(this[PROTO], p);
	return this;
};

ObjectModelProto.toString = function(stack){
	return toString(this[DEFINITION], stack);
};

// private methods
define(ObjectModelProto, VALIDATOR, function(obj, path, callStack, errorStack){
	if(!isObject(obj)){
		var err = {};
		err[EXPECTED] = this;
		err[RECEIVED] = obj;
		err[PATH] = path;
		errorStack.push(err);
	} else {
		checkDefinition(obj, this[DEFINITION], path, callStack, errorStack);
	}
	checkAssertions(obj, this);
});

function getProxy(model, obj, defNode, path) {
	if(defNode instanceof Model && obj && !(obj instanceof defNode)) {
		return defNode(obj);
	} else if(isLeaf(defNode)){
		return obj;
	} else {
		var wrapper = obj instanceof O ? obj : {};
		var proxy = O.create(O.getPrototypeOf(wrapper));

		for(var key in wrapper){
			if(wrapper.hasOwnProperty(key) && !(key in defNode)){
				proxy[key] = wrapper[key]; // properties out of model definition are kept
			}
		}

		O.keys(defNode).forEach(function(key) {
			var newPath = (path ? path + '.' + key : key);
			var isConstant = Model[CONVENTION_CONSTANT](key);
			defineProperty(proxy, key, {
				get: function () {
					return getProxy(model, wrapper[key], defNode[key], newPath);
				},
				set: function (val) {
					if(isConstant && wrapper[key] !== undefined){
						var err = {};
						err[MESSAGE] = "cannot redefine constant " + key;
						model[ERROR_STACK].push(err);
					}
					var newProxy = getProxy(model, val, defNode[key], newPath);
					checkDefinition(newProxy, defNode[key], newPath, [], model[ERROR_STACK]);
					var oldValue = wrapper[key];
					wrapper[key] = newProxy;
					checkAssertions(obj, model);
					if(model[ERROR_STACK].length){
						wrapper[key] = oldValue;
						model[UNSTACK]();
					}
				},
				enumerable: !Model[CONVENTION_PRIVATE](key)
			});
		});
		return proxy;
	}
}<commit_msg>fix #24 , strategy proposal for automatic model casting with union types<commit_after>Model[OBJECT] = function ObjectModel(def){

	var model = function(obj) {
		if(!(this instanceof model)){
			return new model(obj);
		}
		merge(this, obj, true);
		var proxy = getProxy(model, this, model[DEFINITION]);
		model[VALIDATE](proxy);
		return proxy;
	};

	setConstructorProto(model, O[PROTO]);
	initModel(model, def, Model[OBJECT]);
	return model;
};

setConstructorProto(Model[OBJECT], ModelProto);
var ObjectModelProto = Model[OBJECT][PROTO];

ObjectModelProto[DEFAULTS] = function(p){
	merge(this[PROTO], p);
	return this;
};

ObjectModelProto.toString = function(stack){
	return toString(this[DEFINITION], stack);
};

// private methods
define(ObjectModelProto, VALIDATOR, function(obj, path, callStack, errorStack){
	if(!isObject(obj)){
		var err = {};
		err[EXPECTED] = this;
		err[RECEIVED] = obj;
		err[PATH] = path;
		errorStack.push(err);
	} else {
		checkDefinition(obj, this[DEFINITION], path, callStack, errorStack);
	}
	checkAssertions(obj, this);
});

function getProxy(model, obj, defNode, path) {
	if(defNode instanceof Model && obj && !(obj instanceof defNode)) {
		return defNode(obj);
	} else if(isArray(defNode)){
		var suitableModels = defNode.filter(function(part){
			return part instanceof Model && obj && !(obj instanceof part) && part.test(obj)
		})
		return suitableModels.length === 1 ? suitableModels[0](obj) : obj; // when ambiguous, do not cast at all
	} else if(isLeaf(defNode)){
		return obj;
	} else {
		var wrapper = obj instanceof O ? obj : {};
		var proxy = O.create(O.getPrototypeOf(wrapper));

		for(var key in wrapper){
			if(wrapper.hasOwnProperty(key) && !(key in defNode)){
				proxy[key] = wrapper[key]; // properties out of model definition are kept
			}
		}

		O.keys(defNode).forEach(function(key) {
			var newPath = (path ? path + '.' + key : key);
			var isConstant = Model[CONVENTION_CONSTANT](key);
			defineProperty(proxy, key, {
				get: function () {
					return getProxy(model, wrapper[key], defNode[key], newPath);
				},
				set: function (val) {
					if(isConstant && wrapper[key] !== undefined){
						var err = {};
						err[MESSAGE] = "cannot redefine constant " + key;
						model[ERROR_STACK].push(err);
					}
					var newProxy = getProxy(model, val, defNode[key], newPath);
					checkDefinition(newProxy, defNode[key], newPath, [], model[ERROR_STACK]);
					var oldValue = wrapper[key];
					wrapper[key] = newProxy;
					checkAssertions(obj, model);
					if(model[ERROR_STACK].length){
						wrapper[key] = oldValue;
						model[UNSTACK]();
					}
				},
				enumerable: !Model[CONVENTION_PRIVATE](key)
			});
		});
		return proxy;
	}
}<|endoftext|>


<commit_before>// Publish single user

Meteor.publish('user', function(username) {
	return Meteor.users.find({username: username});
});

Meteor.publishComposite('userWithProfilePosts', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return ProfilePosts.find({userId: user._id});
				},
				children: [
					{
						// Publish the poster as well if it wasn't a status update
						find: function(profilePost, user) {
							if (profilePost.statusUpdate === false) {
								return Meteor.users.find({_id: profilePost.posterId}, {fields: requireCollectionFields.user.defaultFields});
							}
						}
					},
					{

						// Publish the profile post's comments
						find: function(profilePost, user) {

							return Comments.find({contentId: profilePost._id, type: 'profilePost'});

						},
						children : [
							{
								find: function(comment, profilePost, user) {
									// Publish users if it isn't published
									if (comment.userId !== user._id && comment.userId !== profilePost.posterId) {
										return Meteor.users.find({_id: comment.userId}, {fields: requireCollectionFields.user.defaultFields});
									}
								}
							}

						]

					}

				]
			}
		]
	};

});

Meteor.publishComposite('userWithActivity', function(username, limit) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return Activity.find({userId: user._id}, {sort: {createdAt: -1}, limit: limit});
				},
				children: [
					{
						// Get library entry children
						find: function(activity, user) {
							if (activity.type === 'libraryEntry') {
								// Grab content
								if (activity.libraryEntry.type === 'anime') {
									return Anime.find({_id: activity.libraryEntry.contentId});
								}
							}
						}
					}
				]
			}
		]
	};

});

Meteor.publishComposite('userWithLibraryEntries', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {

					// If user's profile is not current profile we don't publish private entries
					if (user._id !== this.userId) {
						return LibraryEntries.find({userId: user._id, privacy: {$ne: true}}, {sort: {createdAt: -1}});
					} else {
						return LibraryEntries.find({userId: user._id}, {sort: {createdAt: -1}});
					}
				},
				children: [
					{
						find: function(libraryEntry, user) {

							return Anime.find({_id: libraryEntry.animeId}, {fields: requireCollectionFields.anime.requiredLibraryEntry});

						}
					}
				]
			}

		]
	};

});

Meteor.publishComposite('userWithFollowers', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					if (user.followers) {
						return Meteor.users.find({_id: {$in: user.followers}}, {fields: requireCollectionFields.user.defaultFields});
					}
				}
			}

		]
	};

});

Meteor.publishComposite('userWithFollowing', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					if (user.following) {
						return Meteor.users.find({_id: {$in: user.following}}, {fields: requireCollectionFields.user.defaultFields});
					}
				}
			}

		]
	};

});

Meteor.publishComposite('userWithRevisions', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return Revisions.find({userId: user._id});
				}
			}
		]
	};

});

Meteor.publish('userAlerts', function(userId) {
	// Grab the currently logged in user's alerts
	return Alerts.find({userId: this.userId});
});<commit_msg>Slight fix in the initial publication of libraryEntries, this should improve load times by quite a bit<commit_after>// Publish single user

Meteor.publish('user', function(username) {
	return Meteor.users.find({username: username});
});

Meteor.publishComposite('userWithProfilePosts', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return ProfilePosts.find({userId: user._id});
				},
				children: [
					{
						// Publish the poster as well if it wasn't a status update
						find: function(profilePost, user) {
							if (profilePost.statusUpdate === false) {
								return Meteor.users.find({_id: profilePost.posterId}, {fields: requireCollectionFields.user.defaultFields});
							}
						}
					},
					{

						// Publish the profile post's comments
						find: function(profilePost, user) {

							return Comments.find({contentId: profilePost._id, type: 'profilePost'});

						},
						children : [
							{
								find: function(comment, profilePost, user) {
									// Publish users if it isn't published
									if (comment.userId !== user._id && comment.userId !== profilePost.posterId) {
										return Meteor.users.find({_id: comment.userId}, {fields: requireCollectionFields.user.defaultFields});
									}
								}
							}

						]

					}

				]
			}
		]
	};

});

Meteor.publishComposite('userWithActivity', function(username, limit) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return Activity.find({userId: user._id}, {sort: {createdAt: -1}, limit: limit});
				},
				children: [
					{
						// Get library entry children
						find: function(activity, user) {
							if (activity.type === 'libraryEntry') {
								// Grab content
								if (activity.libraryEntry.type === 'anime') {
									return Anime.find({_id: activity.libraryEntry.contentId});
								}
							}
						}
					}
				]
			}
		]
	};

});

Meteor.publishComposite('userWithLibraryEntries', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {

					// If user's profile is not current profile we don't publish private entries
					if (user._id !== this.userId) {
						return LibraryEntries.find({userId: user._id, privacy: {$ne: true}}, {sort: {createdAt: -1}, limit: 6});
					} else {
						return LibraryEntries.find({userId: user._id}, {sort: {createdAt: -1}, limit: 6});
					}
				},
				children: [
					{
						find: function(libraryEntry, user) {

							return Anime.find({_id: libraryEntry.animeId}, {fields: requireCollectionFields.anime.requiredLibraryEntry});

						}
					}
				]
			}

		]
	};

});

Meteor.publishComposite('userWithFollowers', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					if (user.followers) {
						return Meteor.users.find({_id: {$in: user.followers}}, {fields: requireCollectionFields.user.defaultFields});
					}
				}
			}

		]
	};

});

Meteor.publishComposite('userWithFollowing', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					if (user.following) {
						return Meteor.users.find({_id: {$in: user.following}}, {fields: requireCollectionFields.user.defaultFields});
					}
				}
			}

		]
	};

});

Meteor.publishComposite('userWithRevisions', function(username) {
	return {
		find: function() {
			return Meteor.users.find({username: username});
		},
		children: [
			{
				find: function(user) {
					return Revisions.find({userId: user._id});
				}
			}
		]
	};

});

Meteor.publish('userAlerts', function(userId) {
	// Grab the currently logged in user's alerts
	return Alerts.find({userId: this.userId});
});<|endoftext|>


<commit_before>/*global $,console */
(function ($) {
	'use strict';
	$.fn.exampleInteraction = function () { // function (options)
		return this.each(function() {
			var main = {
				/*options : $.extend({},options),*/
				elements : {
					parent : null
				},
				/*values : {},*/
				init : function (el) {
					var that = this;

					this.elements.parent = el;
					this.elements.parent.on('click.exampleInteraction', function (event) {
						event.preventDefault();
						event.stopPropagation();
						// Your stuff here
						console.log($(this));
					});
				}
			};

			main.init($(this));
		});
	};
}($));

// You may want to move this someplace else
$(document).ready(function() {
	'use strict';
	$('.js-exampleInteraction').exampleInteraction();
});
<commit_msg>Update main.js<commit_after>/*global $ */
(function ($) {
	'use strict';
	$.fn.exampleInteraction = function () { // function (options)
		return this.each(function() {
			var main = {
				/*options : $.extend({},options),*/
				elements : {
					parent : null
				},
				/*values : {},*/
				init : function (el) {
					var that = this;

					this.elements.parent = el;
					this.elements.parent.on('click.exampleInteraction', function (event) {
						event.preventDefault();
						event.stopPropagation();
						// Your stuff here
						console.log($(this));
					});
				}
			};

			main.init($(this));
		});
	};
}($));

// You may want to move this someplace else
$(document).ready(function() {
	'use strict';
	$('.js-exampleInteraction').exampleInteraction();
});
<|endoftext|>


<commit_before>var debugInfo = function(context, ctx, lineSeparator) {
    var result="";
    if (context.dumpLineNumbers && !context.compress) {
        switch(context.dumpLineNumbers) {
            case 'comments':
                result = debugInfo.asComment(ctx);
                break;
            case 'mediaquery':
                result = debugInfo.asMediaQuery(ctx);
                break;
            case 'all':
                result = debugInfo.asComment(ctx) + (lineSeparator || "") + debugInfo.asMediaQuery(ctx);
                break;
        }
    }
    return result;
};

debugInfo.asComment = function(ctx) {
    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
};

debugInfo.asMediaQuery = function(ctx) {
    return '@media -sass-debug-info{filename{font-family:' +
        ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) {
            if (a == '\\') {
                a = '\/';
            }
            return '\\' + a;
        }) +
        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
};

module.exports = debugInfo;
<commit_msg>Prevent double protocol in debug info. Fixes #2383<commit_after>var debugInfo = function(context, ctx, lineSeparator) {
    var result="";
    if (context.dumpLineNumbers && !context.compress) {
        switch(context.dumpLineNumbers) {
            case 'comments':
                result = debugInfo.asComment(ctx);
                break;
            case 'mediaquery':
                result = debugInfo.asMediaQuery(ctx);
                break;
            case 'all':
                result = debugInfo.asComment(ctx) + (lineSeparator || "") + debugInfo.asMediaQuery(ctx);
                break;
        }
    }
    return result;
};

debugInfo.asComment = function(ctx) {
    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
};

debugInfo.asMediaQuery = function(ctx) {
    var filenameWithProtocol = ctx.debugInfo.fileName;
    if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
        filenameWithProtocol = 'file://' + filenameWithProtocol;
    }
    return '@media -sass-debug-info{filename{font-family:' +
        filenameWithProtocol.replace(/([.:\/\\])/g, function (a) {
            if (a == '\\') {
                a = '\/';
            }
            return '\\' + a;
        }) +
        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
};

module.exports = debugInfo;
<|endoftext|>


<commit_before>import React, {Component, Fragment} from 'react';
import round from 'lodash/round';

import Table from 'src/Table';
import Switcher from 'src/Switcher';
import IconButton from 'src/IconButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';
import RaisedButton from 'src/RaisedButton';

import PropTypeDescTable from 'components/PropTypeDescTable';
import doc from 'assets/propTypes/Table.json';

import 'scss/containers/app/modules/layout/TableExamples.scss';

class TableExamples extends Component {

    constructor(props) {

        super(props);

        this.state = {
            data: this.generateData(),
            sort: null
        };

        this.columns = [{
            fixed: Table.Fixed.LEFT,
            headRenderer: 'ID',
            bodyRenderer: 'id',
            footRenderer: 'Total',
            footSpan: 2,
            sortable: true,
            sortingProp: 'id'
        }, {
            fixed: Table.Fixed.LEFT,
            width: 300,
            headRenderer: 'Name',
            bodyRenderer: '${firstName} ${lastName}',
            sortable: true,
            sortingProp: 'firstName'
        }, {
            headRenderer: 'Age',
            headAlign: Table.Align.RIGHT,
            bodyRenderer: 'age',
            bodyAlign: Table.Align.RIGHT,
            footRenderer: () => {
                const {data} = this.state;
                return (
                    <Fragment>

Average

{data.reduce((a, b) => a + b.age, 0) / data.length}

                    </Fragment>
                );
            },
            footAlign: Table.Align.RIGHT,
            sortable: true,
            sortingProp: 'age'
        }, {
            width: 300,
            headRenderer: 'Other Column 1',
            bodyRenderer: '${other} 1'
        }, {
            width: 300,
            headRenderer: 'Other Column 2',
            bodyRenderer: '${other} 2'
        }, {
            width: 300,
            headRenderer: 'Other Column 3',
            bodyRenderer: '${other} 3'
        }, {
            width: 300,
            headRenderer: 'Other Column 4',
            bodyRenderer: '${other} 4'
        }, {
            headRenderer: 'Deposit',
            headAlign: Table.Align.RIGHT,
            bodyRenderer: '$${deposit}',
            bodyAlign: Table.Align.RIGHT,
            footRenderer: () =>
                <Fragment>

Sum

${this.state.data.reduce((a, b) => round(a + b.deposit, 2), 0)}

                </Fragment>,
            footAlign: Table.Align.RIGHT,
            sortable: true,
            sortingProp: 'deposit'
        }, {
            fixed: Table.Fixed.RIGHT,
            headRenderer: 'Status',
            bodyRenderer: rowData =>
                <Switcher value={!rowData.disabled}
                          size="small"
                          onClick={e => e.stopPropagation()}/>
        }];

        this.pageSizes = [{
            value: 10,
            text: '10 / page'
        }, {
            value: 20,
            text: '20 / page'
        }, {
            value: 30,
            text: '30 / page'
        }, {
            value: 40,
            text: '40 / page'
        }, {
            value: 50,
            text: '50 / page'
        }];

    }

    generateData = (size = 100) => {

        let data = [];
        for (let i = 0; i < size; i++) {
            data.push({
                id: i,
                firstName: `firstName${i}`,
                lastName: `lastName${i}`,
                age: Math.floor(Math.random() * 100),
                deposit: round(Math.random() * 1000000, 2),
                other: 'Other Content'
            });
        }

        return data;

    };

    deleteRow = id => {

        const {data} = this.state,
            newData = data.filter(item => item.id !== id);

        this.setState({
            data: newData
        });

    };

    sortHandler = sort => {
        this.setState({
            sort
        });
        console.log('Sort Change Value: ', sort);
    };

    pageChangeHandler = (page, pageSize) => {
        console.log(`page: ${page}, pageSize: ${pageSize}`);
    };

    dataUpdateHandler = currentPageData => {
        console.log('Data Update Value: ', currentPageData);
    };

    selectHandler = (rowData, rowIndex, value) => {
        console.log('Select Value: ', rowData);
    };

    deselectHandler = (rowData, rowIndex, value) => {
        console.log('Deselect Value: ', rowData);
    };

    selectAllHandler = value => {
        console.log('Select All Value: ', value);
    };

    deselectAllHandler = value => {
        console.log('Deselect All Value: ', value);
    };

    changeHandler = value => {
        console.log('Changed Value: ', value);
    };

    clearSort = () => {
        this.setState({
            sort: null
        });
    };

    render() {

        const {data, sort} = this.state;

        return (

Table

                    Table
                     are used to display data and to organize it.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="With isPagging"/>

A simple Table example.

                            <RaisedButton className="table-action"
                                          theme={RaisedButton.Theme.PRIMARY}
                                          value="Clear Table Sort"
                                          onClick={this.clearSort}/>

                                           <IconButton iconCls="fas fa-trash-alt"
                                                       onClick={() => this.deleteRow(rowData.id)}/>
                                   }]}
                                   sort={sort}
                                   isHeadFixed={true}
                                   isFootFixed={true}
                                   scroll={{
                                       width: 1200,
                                       height: 400
                                   }}
                                   paggingCountRenderer={count => Self Defined Total Count: {count}}
                                   onSortChange={this.sortHandler}
                                   onPageChange={this.pageChangeHandler}
                                   onDataUpdate={this.dataUpdateHandler}/>

                </Widget>

                {/*<Widget>*/}

                {/*<WidgetHeader className="example-header" title="With hasLineNumber and isMultiSelect"/>*/}

                {/*
*/}
                {/*
*/}

                {/*
A more complex example.Set the hasLineNumber and isMultiSelect*/}
                {/*to true for showLineNumber and checkbox.
*/}

                {/*<Table data={data}*/}
                {/*columns={this.columns}*/}
                {/*selectMode={Table.SelectMode.MULTI_SELECT}*/}
                {/*selectAllMode={Table.SelectAllMode.CURRENT_PAGE}*/}
                {/*paggingSelectedCountVisible={true}*/}
                {/*defaultPageSize={20}*/}
                {/*pageSizes={this.pageSizes}*/}
                {/*useFullPagging={true}*/}
                {/*sortingAscIconCls="fas fa-caret-up"*/}
                {/*sortingDescIconCls="fas fa-caret-down"*/}
                {/*onPageChange={this.pageChangeHandler}*/}
                {/*onSelect={this.selectHandler}*/}
                {/*onDeselect={this.deselectHandler}*/}
                {/*onSelectAll={this.selectAllHandler}*/}
                {/*onDeselectAll={this.deselectAllHandler}*/}
                {/*onChange={this.changeHandler}/>*/}

                {/*
*/}
                {/*
*/}

                {/*</Widget>*/}

                {/*<Widget>*/}

                {/*<WidgetHeader className="example-header" title="Empty"/>*/}

                {/*
*/}
                {/*
*/}
                {/*
*/}
                {/*
*/}
                {/*
*/}

                {/*</Widget>*/}

Properties

                <PropTypeDescTable data={doc}/>

        );
    }
}

export default TableExamples;
<commit_msg>update TableExamples<commit_after>import React, {Component, Fragment} from 'react';
import round from 'lodash/round';

import Table from 'src/Table';
import Switcher from 'src/Switcher';
import IconButton from 'src/IconButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';
import RaisedButton from 'src/RaisedButton';

import PropTypeDescTable from 'components/PropTypeDescTable';
import doc from 'assets/propTypes/Table.json';

import 'scss/containers/app/modules/layout/TableExamples.scss';

class TableExamples extends Component {

    constructor(props) {

        super(props);

        this.state = {
            data: this.generateData(),
            sort: null
        };

        this.columns = [{
            fixed: Table.Fixed.LEFT,
            headRenderer: 'ID',
            bodyRenderer: 'id',
            footRenderer: 'Total',
            footSpan: 2,
            sortable: true,
            sortingProp: 'id'
        }, {
            fixed: Table.Fixed.LEFT,
            width: 300,
            headRenderer: 'Name',
            bodyRenderer: '${firstName} ${lastName}',
            sortable: true,
            sortingProp: 'firstName'
        }, {
            headRenderer: 'Age',
            headAlign: Table.Align.RIGHT,
            bodyRenderer: 'age',
            bodyAlign: Table.Align.RIGHT,
            footRenderer: () => {
                const {data} = this.state;
                return (
                    <Fragment>

Average

{data.reduce((a, b) => a + b.age, 0) / data.length}

                    </Fragment>
                );
            },
            footAlign: Table.Align.RIGHT,
            sortable: true,
            sortingProp: 'age'
        }, {
            width: 300,
            headRenderer: 'Other Column 1',
            bodyRenderer: '${other} 1'
        }, {
            width: 300,
            headRenderer: 'Other Column 2',
            bodyRenderer: '${other} 2'
        }, {
            width: 300,
            headRenderer: 'Other Column 3',
            bodyRenderer: '${other} 3'
        }, {
            width: 300,
            headRenderer: 'Other Column 4',
            bodyRenderer: '${other} 4'
        }, {
            headRenderer: 'Deposit',
            headAlign: Table.Align.RIGHT,
            bodyRenderer: '$${deposit}',
            bodyAlign: Table.Align.RIGHT,
            footRenderer: () =>
                <Fragment>

Sum

${this.state.data.reduce((a, b) => round(a + b.deposit, 2), 0)}

                </Fragment>,
            footAlign: Table.Align.RIGHT,
            sortable: true,
            sortingProp: 'deposit'
        }, {
            fixed: Table.Fixed.RIGHT,
            headRenderer: 'Status',
            bodyRenderer: rowData =>
                <Switcher value={!rowData.disabled}
                          size="small"
                          onClick={e => e.stopPropagation()}/>
        }];

        this.pageSizes = [{
            value: 10,
            text: '10 / page'
        }, {
            value: 20,
            text: '20 / page'
        }, {
            value: 30,
            text: '30 / page'
        }, {
            value: 40,
            text: '40 / page'
        }, {
            value: 50,
            text: '50 / page'
        }];

    }

    generateData = (size = 100) => {

        let data = [];
        for (let i = 0; i < size; i++) {
            data.push({
                id: i,
                firstName: `firstName${i}`,
                lastName: `lastName${i}`,
                age: Math.floor(Math.random() * 100),
                deposit: round(Math.random() * 1000000, 2),
                other: 'Other Content'
            });
        }

        return data;

    };

    deleteRow = id => {

        const {data} = this.state,
            newData = data.filter(item => item.id !== id);

        this.setState({
            data: newData
        });

    };

    sortHandler = sort => {
        this.setState({
            sort
        });
        console.log('Sort Change Value: ', sort);
    };

    pageChangeHandler = (page, pageSize) => {
        console.log(`page: ${page}, pageSize: ${pageSize}`);
    };

    dataUpdateHandler = currentPageData => {
        console.log('Data Update Value: ', currentPageData);
    };

    selectHandler = (rowData, rowIndex, value) => {
        console.log('Select Value: ', rowData);
    };

    deselectHandler = (rowData, rowIndex, value) => {
        console.log('Deselect Value: ', rowData);
    };

    selectAllHandler = value => {
        console.log('Select All Value: ', value);
    };

    deselectAllHandler = value => {
        console.log('Deselect All Value: ', value);
    };

    changeHandler = value => {
        console.log('Changed Value: ', value);
    };

    clearSort = () => {
        this.setState({
            sort: null
        });
    };

    render() {

        const {data, sort} = this.state;

        return (

Table

                    Table
                     are used to display data and to organize it.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="With isPagging"/>

A simple Table example.

                            <RaisedButton className="table-action"
                                          theme={RaisedButton.Theme.PRIMARY}
                                          value="Clear Table Sort"
                                          onClick={this.clearSort}/>

                                           <IconButton iconCls="fas fa-trash-alt"
                                                       onClick={() => this.deleteRow(rowData.id)}/>
                                   }]}
                                   sort={sort}
                                   selectMode={Table.SelectMode.MULTI_SELECT}
                                   isHeadFixed={true}
                                   isFootFixed={true}
                                   scroll={{
                                       width: 1200,
                                       height: 400
                                   }}
                                   paggingCountRenderer={count => Self Defined Total Count: {count}}
                                   onSortChange={this.sortHandler}
                                   onPageChange={this.pageChangeHandler}
                                   onDataUpdate={this.dataUpdateHandler}/>

                </Widget>

                {/*<Widget>*/}

                {/*<WidgetHeader className="example-header" title="With hasLineNumber and isMultiSelect"/>*/}

                {/*
*/}
                {/*
*/}

                {/*
A more complex example.Set the hasLineNumber and isMultiSelect*/}
                {/*to true for showLineNumber and checkbox.
*/}

                {/*<Table data={data}*/}
                {/*columns={this.columns}*/}
                {/*selectMode={Table.SelectMode.MULTI_SELECT}*/}
                {/*selectAllMode={Table.SelectAllMode.CURRENT_PAGE}*/}
                {/*paggingSelectedCountVisible={true}*/}
                {/*defaultPageSize={20}*/}
                {/*pageSizes={this.pageSizes}*/}
                {/*useFullPagging={true}*/}
                {/*sortingAscIconCls="fas fa-caret-up"*/}
                {/*sortingDescIconCls="fas fa-caret-down"*/}
                {/*onPageChange={this.pageChangeHandler}*/}
                {/*onSelect={this.selectHandler}*/}
                {/*onDeselect={this.deselectHandler}*/}
                {/*onSelectAll={this.selectAllHandler}*/}
                {/*onDeselectAll={this.deselectAllHandler}*/}
                {/*onChange={this.changeHandler}/>*/}

                {/*
*/}
                {/*
*/}

                {/*</Widget>*/}

                {/*<Widget>*/}

                {/*<WidgetHeader className="example-header" title="Empty"/>*/}

                {/*
*/}
                {/*
*/}
                {/*
*/}
                {/*
*/}
                {/*
*/}

                {/*</Widget>*/}

Properties

                <PropTypeDescTable data={doc}/>

        );
    }
}

export default TableExamples;
<|endoftext|>