@@ -87,7 +87,7 @@ cur_frm.cscript.hide_allow_attach = function(doc, dt, dn) { | |||
} | |||
cur_frm.confirm = function(msg, doc, dt, dn) { | |||
var d = new wn.widgets.Dialog({ | |||
var d = new wn.ui.Dialog({ | |||
title: 'Reset To Defaults', | |||
width: 500 | |||
}); | |||
@@ -132,7 +132,7 @@ cur_frm.add_fields_help = function() { | |||
<a id="fields_help" class="link_type">Help</a>\ | |||
</div>'); | |||
$('#fields_help').click(function() { | |||
var d = new wn.widgets.Dialog({ | |||
var d = new wn.ui.Dialog({ | |||
title: 'Help: Field Properties', | |||
width: 600 | |||
}); | |||
@@ -147,7 +147,7 @@ wn.RoleEditor = Class.extend({ | |||
}, | |||
make_perm_dialog: function() { | |||
this.perm_dialog = new wn.widgets.Dialog({ | |||
this.perm_dialog = new wn.ui.Dialog({ | |||
title:'Role Permissions', | |||
width: 500 | |||
}); | |||
@@ -3,28 +3,28 @@ | |||
# These values are common in all dictionaries | |||
{ | |||
'creation': '2012-05-15 12:14:24', | |||
'docstatus': 0, | |||
'modified': '2012-06-13 18:50:36', | |||
'modified_by': u'Administrator', | |||
'owner': u'Administrator' | |||
u'creation': '2012-06-13 19:07:26', | |||
u'docstatus': 0, | |||
u'modified': '2012-10-01 14:00:02', | |||
u'modified_by': u'Administrator', | |||
u'owner': u'Administrator' | |||
}, | |||
# These values are common for all DocType | |||
{ | |||
'allow_trash': 1, | |||
'colour': u'White:FFF', | |||
'doctype': 'DocType', | |||
u'doctype': u'DocType', | |||
'module': u'Core', | |||
'name': '__common__', | |||
u'name': u'__common__', | |||
'section_style': u'Simple', | |||
'version': 1 | |||
}, | |||
# These values are common for all DocField | |||
{ | |||
'doctype': u'DocField', | |||
'name': '__common__', | |||
u'doctype': u'DocField', | |||
u'name': u'__common__', | |||
'parent': u'Report', | |||
'parentfield': u'fields', | |||
'parenttype': u'DocType', | |||
@@ -33,8 +33,8 @@ | |||
# These values are common for all DocPerm | |||
{ | |||
'doctype': u'DocPerm', | |||
'name': '__common__', | |||
u'doctype': u'DocPerm', | |||
u'name': u'__common__', | |||
'parent': u'Report', | |||
'parentfield': u'permissions', | |||
'parenttype': u'DocType', | |||
@@ -44,50 +44,59 @@ | |||
# DocType, Report | |||
{ | |||
'doctype': 'DocType', | |||
'name': u'Report' | |||
u'doctype': u'DocType', | |||
u'name': u'Report' | |||
}, | |||
# DocField | |||
{ | |||
u'doctype': u'DocField', | |||
'fieldname': u'query', | |||
'fieldtype': u'Text', | |||
'label': u'Query' | |||
}, | |||
# DocField | |||
{ | |||
u'doctype': u'DocField', | |||
'fieldname': u'json', | |||
'fieldtype': u'Text', | |||
'label': u'JSON' | |||
}, | |||
# DocField | |||
{ | |||
u'doctype': u'DocField', | |||
'fieldname': u'ref_doctype', | |||
'fieldtype': u'Data', | |||
'label': u'Ref DocType' | |||
}, | |||
# DocPerm | |||
{ | |||
'cancel': 1, | |||
'doctype': u'DocPerm', | |||
u'doctype': u'DocPerm', | |||
'role': u'Administrator' | |||
}, | |||
# DocPerm | |||
{ | |||
'cancel': 1, | |||
'doctype': u'DocPerm', | |||
'role': u'System Manager' | |||
u'doctype': u'DocPerm', | |||
'role': u'System Manager', | |||
'write': 1 | |||
}, | |||
# DocPerm | |||
{ | |||
'cancel': 1, | |||
'doctype': u'DocPerm', | |||
u'doctype': u'DocPerm', | |||
'role': u'Report Manager' | |||
}, | |||
# DocPerm | |||
{ | |||
'doctype': u'DocPerm', | |||
u'doctype': u'DocPerm', | |||
'role': u'All' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': u'DocField', | |||
'fieldname': u'json', | |||
'fieldtype': u'Text', | |||
'label': u'JSON' | |||
}, | |||
# DocField | |||
{ | |||
'doctype': u'DocField', | |||
'fieldname': u'ref_doctype', | |||
'fieldtype': u'Data', | |||
'label': u'Ref DocType' | |||
} | |||
] |
@@ -0,0 +1,11 @@ | |||
wn.pages['query-report'].onload = function(wrapper) { | |||
wn.ui.make_app_page({ | |||
parent: wrapper, | |||
title: 'Query Report', | |||
single_column: true | |||
}); | |||
wn.test = new wn.views.QueryReport({ | |||
parent: wrapper, | |||
}) | |||
} |
@@ -0,0 +1,28 @@ | |||
# Page, query-report | |||
[ | |||
# These values are common in all dictionaries | |||
{ | |||
u'creation': '2012-10-01 10:35:32', | |||
u'docstatus': 0, | |||
u'modified': '2012-10-01 10:35:32', | |||
u'modified_by': u'Administrator', | |||
u'owner': u'Administrator' | |||
}, | |||
# These values are common for all Page | |||
{ | |||
u'doctype': u'Page', | |||
'module': u'Core', | |||
u'name': u'__common__', | |||
'page_name': u'query-report', | |||
'standard': u'Yes', | |||
'title': u'Query Report' | |||
}, | |||
# Page, query-report | |||
{ | |||
u'doctype': u'Page', | |||
u'name': u'query-report' | |||
} | |||
] |
@@ -141,6 +141,7 @@ | |||
"lib/public/js/wn/views/formview.js", | |||
"lib/public/js/wn/views/reportview.js", | |||
"lib/public/js/wn/views/grid_report.js", | |||
"lib/public/js/wn/views/query_report.js", | |||
"lib/public/js/legacy/widgets/dialog.js", | |||
"lib/public/js/legacy/widgets/layout.js", | |||
"lib/public/js/legacy/widgets/tabbedpage.js", | |||
@@ -28,7 +28,7 @@ var cur_dialog; | |||
var top_index=91; | |||
function Dialog(w, h, title, content) { | |||
this.make({width:w, title:title}); | |||
$.extend(this, new wn.ui.Dialog({width:w, title:title})); | |||
if(content)this.make_body(content); | |||
@@ -39,8 +39,6 @@ function Dialog(w, h, title, content) { | |||
this.first_button = false; | |||
} | |||
Dialog.prototype = new wn.widgets.Dialog() | |||
Dialog.prototype.make_body = function(content) { | |||
this.rows = {}; this.widgets = {}; | |||
for(var i in content) this.make_row(content[i]); | |||
@@ -357,7 +357,6 @@ _f.CodeField.prototype.make_input = function() { | |||
//this.input = $a(this.input_area, 'div', '', {position:'relative', width: '90%', height:'300px'}); | |||
wn.require('lib/js/lib/ace/ace.js'); | |||
//wn.require('lib/js/lib/ace/theme-twilight.js'); | |||
$(this.input_area).css('border','1px solid #aaa'); | |||
this.pre = $a(this.input_area, 'pre', '', { | |||
@@ -100,7 +100,7 @@ TagList.prototype.make_add_tag = function() { | |||
TagList.prototype.make_tag_dialog = function() { | |||
var me = this; | |||
var d = new wn.widgets.Dialog({ | |||
var d = new wn.ui.Dialog({ | |||
title: 'Add a tag', | |||
width: 400, | |||
fields: [ | |||
@@ -72,7 +72,7 @@ wn.widgets.form.sidebar.AssignTo = Class.extend({ | |||
add: function() { | |||
var me = this; | |||
if(!me.dialog) { | |||
me.dialog = new wn.widgets.Dialog({ | |||
me.dialog = new wn.ui.Dialog({ | |||
title: 'Add to To Do', | |||
width: 350, | |||
fields: [ | |||
@@ -71,7 +71,7 @@ wn.widgets.form.sidebar.Attachments = function(parent, sidebar, doctype, docname | |||
// using the file mamanger | |||
this.add_attachment = function() { | |||
if(!this.dialog) { | |||
this.dialog = new wn.widgets.Dialog({ | |||
this.dialog = new wn.ui.Dialog({ | |||
title:'Add Attachment', | |||
width: 400 | |||
}) | |||
@@ -51,11 +51,11 @@ classes should alter those! | |||
} | |||
.slick-sort-indicator-desc { | |||
background: url(images/sort-desc.gif); | |||
background: url(lib/js/lib/slickgrid/images/sort-desc.gif); | |||
} | |||
.slick-sort-indicator-asc { | |||
background: url(images/sort-asc.gif); | |||
background: url(lib/js/lib/slickgrid/images/sort-asc.gif); | |||
} | |||
.slick-resizable-handle { | |||
@@ -25,7 +25,7 @@ | |||
wn.provide('wn.ui.misc'); | |||
wn.ui.misc.about = function() { | |||
if(!wn.ui.misc.about_dialog) { | |||
var d = new wn.widgets.Dialog({title:'About wnframework'}) | |||
var d = new wn.ui.Dialog({title:'About wnframework'}) | |||
$(d.body).html(repl("<div style='padding: 20px'<p><b>Application Name:</b> %(name)s</p>\ | |||
<p><b>Version:</b> %(version)s</p>\ | |||
@@ -22,23 +22,32 @@ | |||
// opts { width, height, title, fields (like docfields) } | |||
wn.widgets.FieldGroup = function() { | |||
this.first_button = false; | |||
this.make_fields = function(body, fl) { | |||
wn.provide('wn.ui'); | |||
wn.ui.FieldGroup = Class.extend({ | |||
init: function(opts) { | |||
$.extend(this, opts); | |||
this.make_fields(); | |||
this.catch_enter_as_submit(); | |||
}, | |||
first_button: false, | |||
make_fields: function() { | |||
if(!window.make_field) { | |||
// called in website, load some libs | |||
wn.require('css/fields.css'); | |||
wn.require('js/fields.js'); | |||
} | |||
$y(this.body, {padding:'11px'}); | |||
$(this.parent).css({padding:'11px'}); | |||
this.fields_dict = {}; // reset | |||
for(var i=0; i<fl.length; i++) { | |||
var df = fl[i]; | |||
for(var i=0; i< this.fields.length; i++) { | |||
var df = this.fields[i]; | |||
if(!df.fieldname && df.label) { | |||
df.fieldname = df.label.replace(/ /g, '_').toLowerCase(); | |||
} | |||
var div = $a(body, 'div', '', {margin:'6px 0px'}) | |||
if(!df.fieldtype) df.fieldtype="Data"; | |||
var div = $a(this.parent, 'div', '', {margin:'6px 0px'}) | |||
f = make_field(df, null, div, null); | |||
f.not_in_form = 1; | |||
this.fields_dict[df.fieldname] = f | |||
@@ -50,19 +59,16 @@ wn.widgets.FieldGroup = function() { | |||
this.first_button = true; | |||
} | |||
} | |||
} | |||
this.catch_enter_as_submit = function() { | |||
}, | |||
catch_enter_as_submit: function() { | |||
var me = this; | |||
$(this.body).find(':input[type="text"], :input[type="password"]').keypress(function(e) { | |||
$(this.parent).find(':input[type="text"], :input[type="password"]').keypress(function(e) { | |||
if(e.which==13) { | |||
$(me.body).find('.btn-info:first').click(); | |||
$(me.parent).find('.btn-info:first').click(); | |||
} | |||
}) | |||
} | |||
/* get values */ | |||
this.get_values = function() { | |||
}, | |||
get_values: function() { | |||
var ret = {}; | |||
var errors = []; | |||
for(var key in this.fields_dict) { | |||
@@ -79,27 +85,22 @@ wn.widgets.FieldGroup = function() { | |||
return null; | |||
} | |||
return ret; | |||
} | |||
/* set field value */ | |||
this.set_value = function(key, val){ | |||
}, | |||
set_value: function(key, val){ | |||
var f = this.fields_dict[key]; | |||
if(f) { | |||
f.set_input(val); | |||
f.refresh_mandatory(); | |||
} | |||
} | |||
/* set values from a dict */ | |||
this.set_values = function(dict) { | |||
}, | |||
set_values: function(dict) { | |||
for(var key in dict) { | |||
if(this.fields_dict[key]) { | |||
this.set_value(key, dict[key]); | |||
} | |||
} | |||
} | |||
this.clear = function() { | |||
}, | |||
clear: function() { | |||
for(key in this.fields_dict) { | |||
var f = this.fields_dict[key]; | |||
if(f) { | |||
@@ -107,50 +108,48 @@ wn.widgets.FieldGroup = function() { | |||
} | |||
} | |||
} | |||
} | |||
wn.widgets.Dialog = function(opts) { | |||
this.display = false; | |||
this.make = function(opts) { | |||
if(opts) { | |||
this.opts = opts; | |||
$.extend(this, opts); | |||
} | |||
if(!this.opts.width) this.opts.width = 480; | |||
}); | |||
wn.ui.Dialog = wn.ui.FieldGroup.extend({ | |||
init: function(opts) { | |||
this.display = false; | |||
if(!opts.width) opts.width = 480; | |||
$.extend(this, opts); | |||
this.make(); | |||
// init fields | |||
if(this.fields) { | |||
this.parent = this.body | |||
this._super({}); | |||
} | |||
}, | |||
make: function() { | |||
if(!$('#dialog-container').length) { | |||
$('<div id="dialog-container">').appendTo('body'); | |||
} | |||
this.wrapper = $('<div class="dialog_wrapper">').appendTo('#dialog-container').get(0); | |||
this.wrapper = $('<div class="dialog_wrapper">') | |||
.appendTo('#dialog-container').get(0); | |||
if(this.opts.width) | |||
this.wrapper.style.width = this.opts.width + 'px'; | |||
if(this.width) | |||
this.wrapper.style.width = this.width + 'px'; | |||
this.make_head(); | |||
this.body = $a(this.wrapper, 'div', 'dialog_body'); | |||
if(this.opts.fields) { | |||
this.make_fields(this.body, this.opts.fields); | |||
this.catch_enter_as_submit(); | |||
} | |||
} | |||
this.make_head = function() { | |||
}, | |||
make_head: function() { | |||
var me = this; | |||
this.appframe = new wn.ui.AppFrame(this.wrapper); | |||
this.appframe.$titlebar.find('.close').unbind('click').click(function() { | |||
if(me.oncancel)me.oncancel(); me.hide(); | |||
}); | |||
this.set_title(this.opts.title); | |||
} | |||
this.set_title = function(t) { | |||
this.set_title(this.title); | |||
}, | |||
set_title: function(t) { | |||
this.appframe.$titlebar.find('.appframe-title').html(t || ''); | |||
} | |||
this.set_postion = function() { | |||
}, | |||
set_postion: function() { | |||
// place it at the center | |||
this.wrapper.style.left = (($(window).width() - cint(this.wrapper.style.width))/2) + 'px'; | |||
this.wrapper.style.top = ($(window).scrollTop() + 60) + 'px'; | |||
@@ -158,10 +157,8 @@ wn.widgets.Dialog = function(opts) { | |||
// place it on top | |||
top_index++; | |||
$y(this.wrapper,{zIndex:top_index}); | |||
} | |||
/** show the dialog */ | |||
this.show = function() { | |||
}, | |||
show: function() { | |||
// already live, do nothing | |||
if(this.display) return; | |||
@@ -182,9 +179,8 @@ wn.widgets.Dialog = function(opts) { | |||
// focus on first input | |||
$(this.wrapper).find(':input:first').focus(); | |||
} | |||
this.hide = function() { | |||
}, | |||
hide: function() { | |||
// call onhide | |||
if(this.onhide) this.onhide(); | |||
@@ -195,20 +191,11 @@ wn.widgets.Dialog = function(opts) { | |||
// flags | |||
this.display = false; | |||
cur_dialog = null; | |||
} | |||
this.no_cancel = function() { | |||
}, | |||
no_cancel: function() { | |||
this.appframe.$titlebar.find('.close').toggle(false); | |||
} | |||
if(opts) this.make(opts); | |||
} | |||
wn.widgets.Dialog.prototype = new wn.widgets.FieldGroup(); | |||
wn.provide('wn.ui'); | |||
wn.ui.Dialog = wn.widgets.Dialog | |||
}); | |||
// close open dialogs on ESC | |||
$(document).bind('keydown', function(e) { | |||
@@ -185,7 +185,7 @@ wn.ui.Filter = Class.extend({ | |||
parent: me.field.df.parent, | |||
} : {} | |||
var df = me.fieldselect.fields_by_name[tablename][fieldname]; | |||
var df = copy_dict(me.fieldselect.fields_by_name[tablename][fieldname]); | |||
this.set_fieldtype(df, fieldtype); | |||
// called when condition is changed, | |||
@@ -41,7 +41,7 @@ wn.ui.toolbar.SelectorDialog = Class.extend({ | |||
this.bind_events(); | |||
}, | |||
make_dialog: function() { | |||
this.dialog = new wn.widgets.Dialog({ | |||
this.dialog = new wn.ui.Dialog({ | |||
title: this.opts.title, | |||
width: 300, | |||
fields: [ | |||
@@ -0,0 +1,258 @@ | |||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
// | |||
// MIT License (MIT) | |||
// | |||
// Permission is hereby granted, free of charge, to any person obtaining a | |||
// copy of this software and associated documentation files (the "Software"), | |||
// to deal in the Software without restriction, including without limitation | |||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
// and/or sell copies of the Software, and to permit persons to whom the | |||
// Software is furnished to do so, subject to the following conditions: | |||
// | |||
// The above copyright notice and this permission notice shall be included in | |||
// all copies or substantial portions of the Software. | |||
// | |||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
// | |||
wn.provide("wn.views"); | |||
wn.views.QueryReport = Class.extend({ | |||
init: function(opts) { | |||
$.extend(this, opts); | |||
// globalify for slickgrid | |||
this.appframe = this.parent.appframe; | |||
this.parent.query_report = this; | |||
this.make(); | |||
}, | |||
slickgrid_options: { | |||
enableColumnReorder: false, | |||
showHeaderRow: true, | |||
headerRowHeight: 30, | |||
explicitInitialization: true, | |||
multiColumnSort: true | |||
}, | |||
make: function() { | |||
this.wrapper = $("<div>").appendTo($(this.parent).find(".layout-main")); | |||
$('<div class="query-edit" style="display: none;">\ | |||
<div class="query-form" style="width: 60%; float: left;"></div>\ | |||
<div class="help" style="width: 30%; float: left; margin-left: 15px;">\ | |||
<b>Query Rules:</b><br>\ | |||
<ol>\ | |||
<li>Define column names as JSON objects to specifiy types and links:\ | |||
<li>Labels are automatically defined from column headings.\ | |||
To define for doctype, set `{"label": "Customer", "type": "Link", "options":"Customer"}`\ | |||
<li>For DataTypes, use suffix: eg. `{"label":"Qty", "type":"Float"}`\ | |||
<li>For Links, use suffix "link": eg. `customer:float`\ | |||
</ol>\ | |||
</div>\ | |||
<hr style="clear: both;" />\ | |||
</div>\ | |||
<div class="result-area" style="height:400px; \ | |||
border: 1px solid #aaa;"></div>').appendTo(this.wrapper); | |||
this.make_query_form(); | |||
this.make_toolbar(); | |||
this.import_slickgrid(); | |||
}, | |||
make_toolbar: function() { | |||
var me = this; | |||
this.appframe.add_button("Run", function() { | |||
// Run | |||
wn.call({ | |||
method: "webnotes.widgets.query_report.run", | |||
args: { | |||
query: $(me.wrapper).find("textarea").val() | |||
}, | |||
callback: function(r) { | |||
me.refresh(r.message.result, r.message.columns); | |||
} | |||
}) | |||
}).addClass("btn-success"); | |||
if(in_list(user_roles, "System Manager")) { | |||
// Edit | |||
this.appframe.add_button("Edit", function() { | |||
me.wrapper.find(".query-edit").slideToggle(); | |||
}); | |||
// Save | |||
this.appframe.add_button("Save", function() { | |||
var doc = me.query_form.get_values(); | |||
if(!doc) return; | |||
doc.doctype = "Report" | |||
wn.call({ | |||
method:"webnotes.client.save", | |||
args: { | |||
doclist: [doc], | |||
}, | |||
callback: function(r) { | |||
//wn.set_route("query-form", doc.name); | |||
} | |||
}) | |||
}); | |||
} | |||
}, | |||
make_query_form: function() { | |||
this.query_form = new wn.ui.FieldGroup({ | |||
parent: $(this.wrapper).find(".query-form").get(0), | |||
fields: [ | |||
{label:"Report Name", reqd: 1, fieldname:"name"}, | |||
{label:"Based on", fieldtype:"Link", options:"DocType", | |||
fieldname: "ref_doctype", | |||
reqd:1, description:"Permissions will be based on this DocType"}, | |||
{label:"Query", fieldtype: "Text", reqd: 1} | |||
] | |||
}); | |||
$(this.query_form.fields_dict.query.input).css({ | |||
width: "100%", | |||
height: "300px", | |||
"font-weight": "Normal", | |||
"font-family": "Monaco, Courier, Fixed" | |||
}); | |||
}, | |||
import_slickgrid: function() { | |||
wn.require('lib/js/lib/slickgrid/slick.grid.css'); | |||
wn.require('lib/js/lib/slickgrid/slick-default-theme.css'); | |||
wn.require('lib/js/lib/slickgrid/jquery.event.drag.min.js'); | |||
wn.require('lib/js/lib/slickgrid/slick.core.js'); | |||
wn.require('lib/js/lib/slickgrid/slick.grid.js'); | |||
wn.require('lib/js/lib/slickgrid/slick.dataview.js'); | |||
wn.dom.set_style('.slick-cell { font-size: 12px; }\ | |||
.slick-headerrow-column {\ | |||
background: #87ceeb;\ | |||
text-overflow: clip;\ | |||
-moz-box-sizing: border-box;\ | |||
box-sizing: border-box;\ | |||
}\ | |||
.slick-headerrow-column input {\ | |||
margin: 0;\ | |||
padding: 0;\ | |||
width: 100%;\ | |||
height: 100%;\ | |||
-moz-box-sizing: border-box;\ | |||
box-sizing: border-box;}'); | |||
}, | |||
refresh: function(result, columns) { | |||
this.make_data(result, columns); | |||
this.make_columns(columns); | |||
this.render(result, columns); | |||
}, | |||
render: function(result, columns) { | |||
this.columnFilters = {}; | |||
this.make_dataview(); | |||
this.id = wn.dom.set_unique_id($(this.wrapper.find(".result-area")).get(0)); | |||
this.grid = new Slick.Grid("#"+this.id, this.dataView, this.columns, | |||
this.slickgrid_options); | |||
this.setup_header_row(); | |||
this.grid.init(); | |||
this.setup_sort(); | |||
}, | |||
make_columns: function(columns) { | |||
this.columns = [{id: "_id", field: "_id", name: "Sr No", width: 60}] | |||
.concat($.map(columns, function(c) { | |||
return {id: c, field: c, sortable: true, | |||
name: toTitle(c.replace(/_/g, " ")) } | |||
})); | |||
}, | |||
make_data: function(result, columns) { | |||
this.data = $.map(result, function(row, row_idx) { | |||
var newrow = {}; | |||
$.each(columns, function(i, col) { | |||
newrow[col] = row[i]; | |||
}); | |||
newrow._id = row_idx + 1; | |||
newrow.id = newrow.name ? newrow.name : ("_" + newrow._id); | |||
return newrow; | |||
}); | |||
}, | |||
make_dataview: function() { | |||
// initialize the model | |||
this.dataView = new Slick.Data.DataView({ inlineFilters: true }); | |||
this.dataView.beginUpdate(); | |||
this.dataView.setItems(this.data); | |||
this.dataView.setFilter(this.inline_filter); | |||
this.dataView.endUpdate(); | |||
var me = this; | |||
this.dataView.onRowCountChanged.subscribe(function (e, args) { | |||
me.grid.updateRowCount(); | |||
me.grid.render(); | |||
}); | |||
this.dataView.onRowsChanged.subscribe(function (e, args) { | |||
me.grid.invalidateRows(args.rows); | |||
me.grid.render(); | |||
}); | |||
}, | |||
inline_filter: function (item) { | |||
var me = wn.container.page.query_report; | |||
for (var columnId in me.columnFilters) { | |||
if (columnId !== undefined && me.columnFilters[columnId] !== "") { | |||
var c = me.grid.getColumns()[me.grid.getColumnIndex(columnId)]; | |||
if (!me.compare_values(item[c.field], me.columnFilters[columnId])) { | |||
return false; | |||
} | |||
} | |||
} | |||
return true; | |||
}, | |||
compare_values: function(value, filter) { | |||
value = value + ""; | |||
value = value.toLowerCase(); | |||
filter = filter.toLowerCase(); | |||
if(filter.length < value.length) { | |||
return filter==value.substr(0, filter.length) | |||
} | |||
}, | |||
setup_header_row: function() { | |||
var me = this; | |||
$(this.grid.getHeaderRow()).delegate(":input", "change keyup", function (e) { | |||
var columnId = $(this).data("columnId"); | |||
if (columnId != null) { | |||
me.columnFilters[columnId] = $.trim($(this).val()); | |||
me.dataView.refresh(); | |||
} | |||
}); | |||
this.grid.onHeaderRowCellRendered.subscribe(function(e, args) { | |||
$(args.node).empty(); | |||
$("<input type='text'>") | |||
.data("columnId", args.column.id) | |||
.val(me.columnFilters[args.column.id]) | |||
.appendTo(args.node); | |||
}); | |||
}, | |||
setup_sort: function() { | |||
var me = this; | |||
this.grid.onSort.subscribe(function (e, args) { | |||
var cols = args.sortCols; | |||
me.data.sort(function (dataRow1, dataRow2) { | |||
for (var i = 0, l = cols.length; i < l; i++) { | |||
var field = cols[i].sortCol.field; | |||
var sign = cols[i].sortAsc ? 1 : -1; | |||
var value1 = dataRow1[field], value2 = dataRow2[field]; | |||
var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign; | |||
if (result != 0) { | |||
return result; | |||
} | |||
} | |||
return 0; | |||
}); | |||
me.dataView.beginUpdate(); | |||
me.dataView.setItems(me.data); | |||
me.dataView.endUpdate(); | |||
me.dataView.refresh(); | |||
}); | |||
} | |||
}) |
@@ -247,6 +247,15 @@ def get_roles(user=None, with_standard=True): | |||
return roles | |||
def has_permission(doctype, ptype): | |||
"""check if user has permission""" | |||
return conn.sql("""select name from tabDocPerm p | |||
where p.parent = %s | |||
and ifnull(p.`%s`,0) = 1 | |||
and ifnull(p.permlevel,0) = 0 | |||
and p.role in (select `role` from tabUserRole where `parent`=%s) | |||
""" % ("%s", ptype, "%s"), (doctype, session.user)) | |||
def generate_hash(): | |||
"""Generates random hash for session id""" | |||
import hashlib, time |
@@ -0,0 +1,40 @@ | |||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
# | |||
# MIT License (MIT) | |||
# | |||
# Permission is hereby granted, free of charge, to any person obtaining a | |||
# copy of this software and associated documentation files (the "Software"), | |||
# to deal in the Software without restriction, including without limitation | |||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
# and/or sell copies of the Software, and to permit persons to whom the | |||
# Software is furnished to do so, subject to the following conditions: | |||
# | |||
# The above copyright notice and this permission notice shall be included in | |||
# all copies or substantial portions of the Software. | |||
# | |||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
# | |||
from __future__ import unicode_literals | |||
import webnotes | |||
import json | |||
@webnotes.whitelist() | |||
def save(): | |||
"""insert or update from form query""" | |||
doclist = json.loads(webnotes.form_dict.doclist) | |||
from webnotes.model.doclist import DocList | |||
if not webnotes.has_permission(doclist[0]["doctype"], "write"): | |||
webnotes.msgprint("No Write Permission", raise_exception=True) | |||
doclistobj = DocList(doclist) | |||
doclistobj.save() | |||
webntoes.msgprint("%s: '%s' saved" % form.doctype, form.name) |
@@ -0,0 +1,38 @@ | |||
# Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||
# | |||
# MIT License (MIT) | |||
# | |||
# Permission is hereby granted, free of charge, to any person obtaining a | |||
# copy of this software and associated documentation files (the "Software"), | |||
# to deal in the Software without restriction, including without limitation | |||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
# and/or sell copies of the Software, and to permit persons to whom the | |||
# Software is furnished to do so, subject to the following conditions: | |||
# | |||
# The above copyright notice and this permission notice shall be included in | |||
# all copies or substantial portions of the Software. | |||
# | |||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
# | |||
from __future__ import unicode_literals | |||
import webnotes | |||
@webnotes.whitelist() | |||
def run(): | |||
query = webnotes.form_dict.query | |||
if not query.lower().startswith("select"): | |||
webnotes.msgprint("Query must be a SELECT", raise_exception=True) | |||
result = [list(t) for t in webnotes.conn.sql(query)] | |||
columns = webnotes.conn.get_description() | |||
return { | |||
"result": result, | |||
"columns": [c[0] for c in columns] | |||
} |