Merge branch 'responsive' of github.com:webnotes/wnframework into responsive

This commit is contained in:
Anand Doshi 2013-05-30 11:53:29 +05:30
commit 81675af2f5
17 changed files with 144 additions and 138 deletions

View file

@ -23,19 +23,21 @@
cur_frm.cscript.refresh = function(doc) {
if (doc.docstatus) hide_field('steps');
var has_attachments = !$.isEmptyObject(cur_frm.attachments.get_attachments());
cur_frm.set_intro("");
if(doc.__islocal) {
cur_frm.set_intro("Step 1: Set the name and save.");
} else {
if(!doc.file_list) {
if(has_attachments) {
cur_frm.set_intro("Step 2: Upload your letter head image / set html content directly");
cur_frm.add_custom_button("Upload", function() {
cur_frm.attachments.add_attachment();
}, 'icon-upload');
}, 'icon-upload');
}
}
if(doc.file_list && !doc.content) {
if(has_attachments && !doc.content) {
cur_frm.cscript['set_from_image'](doc);
}
@ -49,7 +51,7 @@ cur_frm.cscript.content = function(doc) {
}
cur_frm.cscript['set_from_image'] = function(doc, dt, dn) {
if(!doc.file_list) {
if(!cur_frm.get_files().length) {
msgprint('Please attach an image file first');
return;
}

View file

@ -210,7 +210,7 @@ _f.Frm.prototype.call_server = function(method, args, callback) {
_f.Frm.prototype.get_files = function() {
return cur_frm.attachments
? keys(cur_frm.attachments.get_file_list()).sort()
? keys(cur_frm.attachments.get_attachments()).sort()
: [] ;
}

View file

@ -655,10 +655,6 @@ _f.Frm.prototype.copy_doc = function(onload, from_amend) {
var dn = this.docname;
// copy parent
var newdoc = wn.model.copy_doc(this.doctype, dn, from_amend);
// do not copy attachments
if(this.meta.allow_attach && newdoc.file_list && !from_amend)
newdoc.file_list = null;
// copy chidren
var dl = make_doclist(this.doctype, dn);
@ -830,5 +826,8 @@ _f.Frm.prototype.set_value_in_locals = function(dt, dn, fn, v) {
_f.Frm.prototype.dirty = function() {
this.doc.__unsaved = 1;
$(this.wrapper).trigger('dirty')
}
_f.Frm.prototype.get_docinfo = function() {
return wn.model.docinfo[this.doctype][this.docname];
}

View file

@ -48,11 +48,11 @@ wn.ui.form.AssignTo = Class.extend({
return;
}
this.parent.toggle(true);
this.render(JSON.parse(this.frm.doc.__assign_to || "[]"));
this.render(this.frm.get_docinfo().assignments);
},
render: function(d) {
var me = this;
this.frm.doc.__assign_to = JSON.stringify(d);
this.frm.get_docinfo().assignments = d;
this.$list.empty();
if(this.dialog) {
this.dialog.hide();

View file

@ -40,7 +40,7 @@ wn.ui.form.Attachments = Class.extend({
},
max_reached: function() {
// no of attachments
var n = keys(this.get_file_list()).length;
var n = keys(this.get_attachments()).length;
// button if the number of attachments is less than max
if(n < this.frm.meta.max_attachments || !this.frm.meta.max_attachments) {
@ -59,22 +59,22 @@ wn.ui.form.Attachments = Class.extend({
this.$list.empty();
var file_list = this.get_file_list();
var file_names = keys(file_list).sort();
var attachments = this.get_attachments();
var file_names = keys(attachments).sort();
// add attachment objects
for(var i=0; i<file_names.length; i++) {
this.add_attachment(file_names[i], file_list);
this.add_attachment(file_names[i], attachments);
}
// refresh select fields with options attach_files:
this.refresh_attachment_select_fields();
},
get_file_list: function() {
return this.frm.doc.file_list ? JSON.parse(this.frm.doc.file_list) : {};
get_attachments: function() {
return this.frm.get_docinfo().attachments;
},
add_attachment: function(filename, file_list) {
var fileid = file_list[filename];
add_attachment: function(filename, attachments) {
var fileid = attachments[filename];
var me = this;
$(repl('<div class="alert alert-info" style="margin-bottom: 7px">\
@ -143,7 +143,7 @@ wn.ui.form.Attachments = Class.extend({
update_attachment: function(fileid, filename, fieldname, r) {
this.dialog && this.dialog.hide();
if(fileid) {
this.add_to_file_list(fileid, filename);
this.add_to_attachments(fileid, filename);
this.refresh();
if(fieldname) {
this.frm.set_value(fieldname, "files/"+filename);
@ -151,20 +151,17 @@ wn.ui.form.Attachments = Class.extend({
}
}
},
add_to_file_list: function(fileid, filename) {
var doc = this.frm.doc;
var file_list = doc.file_list ? this.get_file_list() : {};
file_list[filename] = fileid;
doc.file_list = JSON.stringify(file_list);
add_to_attachments: function(fileid, filename) {
this.get_attachments()[filename] = fileid;
},
remove_fileid: function(fileid) {
var file_list = this.get_file_list();
var new_file_list = {};
$.each(file_list, function(key, value) {
var attachments = this.get_attachments();
var new_attachments = {};
$.each(attachments, function(key, value) {
if(value!=fileid)
new_file_list[key] = value;
new_attachments[key] = value;
});
this.frm.doc.file_list = JSON.stringify(new_file_list);
this.frm.get_docinfo().attachments = new_attachments;
this.refresh();
},
refresh_attachment_select_fields: function() {

View file

@ -23,6 +23,9 @@ wn.ui.form.Comments = Class.extend({
this.list = $('<div class="comments" style="margin-top: 15px;"></div>')
.appendTo(this.parent);
},
get_comments: function() {
return this.frm.get_docinfo().comments;
},
refresh: function() {
var me = this;
if(this.frm.doc.__islocal) {
@ -31,7 +34,7 @@ wn.ui.form.Comments = Class.extend({
}
this.wrapper.toggle(true);
this.list.empty();
var comments = JSON.parse(this.frm.doc.__comments || "[]");
var comments = this.get_comments();
$.each(comments, function(i, c) {
if(wn.model.can_delete("Comment")) {
c["delete"] = '<a class="close" href="#">&times;</a>';
@ -82,8 +85,8 @@ wn.ui.form.Comments = Class.extend({
},
callback: function(r) {
if(!r.exc) {
var comments = JSON.parse(me.frm.doc.__comments || "[]");
me.frm.doc.__comments = JSON.stringify(r.message.concat(comments));
me.frm.get_docinfo().comments =
r.message.concat(me.get_comments());
me.frm.toolbar.show_infobar();
me.input.val("");
me.refresh();
@ -102,14 +105,13 @@ wn.ui.form.Comments = Class.extend({
},
callback: function(r) {
if(!r.exc) {
me.frm.doc.__comments = JSON.stringify(
$.map(JSON.parse(me.frm.doc.__comments || "[]"),
me.frm.get_docinfo().comments =
$.map(me.frm.get_docinfo().comments,
function(v) {
if(v.name==name) return null;
else return v;
}
)
);
);
me.refresh();
me.frm.toolbar.show_infobar();
}

View file

@ -54,6 +54,7 @@ wn.ui.form.Control = Class.extend({
var set = function(value) {
me.set_model_value(value);
me.inside_change_event = false;
me.set_mandatory && me.set_mandatory(value);
}
this.validate ? this.validate(value, set) : set(value);
@ -129,7 +130,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
this.$wrapper = $("<span>").appendTo(this.parent);
} else {
this.$wrapper = $('<div class="control-group">\
<label></label>\
<label class="control-label"></label>\
<div class="control-input"></div>\
<div class="control-value like-disabled-input" style="display: none;"></div>\
<p class="help-box small text-muted">&nbsp;</p>\
@ -183,7 +184,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
me.set_description();
me.set_label();
me.set_mandatory();
me.set_mandatory(me.value);
return false;
}
@ -208,9 +209,9 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
set_empty_description: function() {
this.$wrapper.find(".help-box").html("&nbsp;");
},
set_mandatory: function() {
set_mandatory: function(value) {
this.$wrapper.toggleClass("has-error", (this.df.reqd
&& (this.value==null || this.value==="")) ? true : false);
&& (value==null || value==="")) ? true : false);
},
});
@ -220,7 +221,7 @@ wn.ui.form.ControlData = wn.ui.form.ControlInput.extend({
make_input: function() {
this.$input = $("<"+ this.html_element +">")
.attr("type", this.input_type)
.addClass("col col-lg-12")
.addClass("col col-lg-12 input-with-feedback")
.prependTo(this.input_area)
this.set_input_attributes();
@ -245,9 +246,10 @@ wn.ui.form.ControlData = wn.ui.form.ControlInput.extend({
set_input: function(val) {
this.$input.val(this.format_for_input(val));
this.last_value = val;
this.set_mandatory && this.set_mandatory(val);
},
get_value: function() {
return this.$input.val();
return this.$input ? this.$input.val() : undefined;
},
format_for_input: function(val) {
return val==null ? "" : val;
@ -516,11 +518,10 @@ wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({
},
get_file_attachment_list: function() {
if(!this.frm) return;
var fl = this.frm.doc.file_list;
var fl = wn.model.docinfo[this.frm.doctype][this.frm.docname];
if(fl) {
this.set_description("");
var fl = JSON.parse(fl),
options = [""];
var options = [""];
for(var fname in fl) {
if(fname.substr(0,4)!="http")
fname = "files/" + fname;
@ -543,7 +544,7 @@ wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({
wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({
make_input: function() {
$('<div class="input-group link-field">\
<input type="text">\
<input type="text" class="input-with-feedback">\
<div class="input-group-btn">\
<button class="btn btn-default btn-search" title="Search Link">\
<i class="icon-search"></i>\

View file

@ -19,7 +19,6 @@ wn.ui.form.Toolbar = Class.extend({
}
this.make_file_menu();
this.make_view_menu();
if(!this.frm.view_is_edit) {
// print view
this.show_print_toolbar();
@ -53,9 +52,10 @@ wn.ui.form.Toolbar = Class.extend({
"Last Modifed On: " + dateutil.str_to_user(me.frm.doc.modified), "History");
})
var comments = JSON.parse(this.frm.doc.__comments || "[]").length,
attachments = keys(JSON.parse(this.frm.doc.file_list || "{}")).length,
assignments = JSON.parse(this.frm.doc.__assign_to || "[]").length;
var docinfo = wn.model.docinfo[this.frm.doctype][this.frm.docname];
var comments = docinfo.comments.length,
attachments = keys(docinfo.attachments).length,
assignments = docinfo.assignments.length;
var $li1 = this.appframe.add_infobar(comments + " " + (comments===1 ?
wn._("Comment") : wn._("Comments")),
@ -155,10 +155,22 @@ wn.ui.form.Toolbar = Class.extend({
this.appframe.add_dropdown_button("File", wn._("Email..."), function() {
me.frm.email_doc();}, 'icon-envelope');
}
// Linked With
if(!me.frm.doc.__islocal && !me.frm.meta.issingle) {
this.appframe.add_dropdown_button("File", wn._('Linked With'), function() {
if(!me.frm.linked_with) {
me.frm.linked_with = new wn.ui.form.LinkedWith({
frm: me.frm
});
}
me.frm.linked_with.show();
}, "icon-link")
}
// copy
if(in_list(profile.can_create, me.frm.doctype) && !me.frm.meta.allow_copy) {
this.appframe.add_dropdown_button("File", wn._("Make Copy"), function() {
this.appframe.add_dropdown_button("File", wn._("Copy"), function() {
me.frm.copy_doc();}, 'icon-file');
}
@ -176,33 +188,6 @@ wn.ui.form.Toolbar = Class.extend({
}
},
make_view_menu: function() {
var me = this;
// Edit
if(this.frm.meta.read_only_onload && !this.frm.doc.__islocal) {
this.appframe.add_dropdown_button("View", wn._('Print View'), function() {
me.frm.last_view_is_edit[me.frm.docname] = 0;
me.frm.refresh(); }, 'icon-print');
}
if(this.frm.meta.read_only_onload && !this.frm.doc.__islocal) {
this.appframe.add_dropdown_button("View", wn._('Edit'), function() {
me.frm.last_view_is_edit[me.frm.docname] = 1;
me.frm.refresh(); }, 'icon-edit');
}
// Linked With
if(!me.frm.doc.__islocal && !me.frm.meta.issingle) {
this.appframe.add_dropdown_button("View", wn._('Linked With'), function() {
if(!me.frm.linked_with) {
me.frm.linked_with = new wn.ui.form.LinkedWith({
frm: me.frm
});
}
me.frm.linked_with.show();
}, "icon-link")
}
},
set_title_button: function() {
var me = this;
var docstatus = cint(this.frm.doc.docstatus);
@ -212,6 +197,13 @@ wn.ui.form.Toolbar = Class.extend({
// remove existing title buttons
this.appframe.toolbar.find(".btn-title").remove();
// Print Preview
if(this.frm.meta.read_only_onload && !this.frm.doc.__islocal && this.frm.view_is_edit) {
this.appframe.add_button(wn._('Preview'), function() {
me.frm.last_view_is_edit[me.frm.docname] = 0;
me.frm.refresh(); }, 'icon-print');
}
if(has_workflow && (this.frm.doc.__islocal || this.frm.doc.__unsaved)) {
this.make_save_button();
} else if(!has_workflow) {

View file

@ -5,6 +5,13 @@ wn.utils = {
return wn.utils.is_url(filename) || (filename.indexOf("images/")!=-1) || (filename.indexOf("files/")!=-1)
? filename : 'files/' + filename;
},
is_html: function(txt) {
if(txt.indexOf("<br>")==-1 && txt.indexOf("<p")==-1
&& txt.indexOf("<img")==-1 && txt.indexOf("<div")==-1) {
return false;
}
return true;
},
is_url: function(txt) {
return txt.toLowerCase().substr(0,7)=='http://'
|| txt.toLowerCase().substr(0,8)=='https://'

View file

@ -16,6 +16,7 @@ $.extend(wn.model, {
};
wn.model.set_default_values(doc);
locals[doctype][doc.name] = doc;
wn.provide("wn.model.docinfo." + doctype + "." + doc.name);
return doc;
},

View file

@ -21,7 +21,14 @@
//
$.extend(wn.model, {
sync: function(doclist) {
docinfo: {},
sync: function(r) {
/* docs:
extract doclist, docinfo (attachments, comments, assignments)
from incoming request and set in `locals` and `wn.model.docinfo`
*/
var doclist = r.docs ? r.docs : r;
if(doclist._kl)
doclist = wn.model.expand(doclist);
@ -49,9 +56,23 @@ $.extend(wn.model, {
wn.model.new_names[d.localname] = d.name;
$(document).trigger('rename', [d.doctype, d.localname, d.name]);
delete locals[d.doctype][d.localname];
// update docinfo to new dict keys
if(i===0) {
wn.model.docinfo[d.doctype][d.name] = wn.model.docinfo[d.doctype][d.localname];
wn.model.docinfo[d.doctype][d.localname] = undefined;
}
}
});
// set docinfo
if(r.docinfo) {
var doc = doclist[0]
if(!wn.model.docinfo[doc.doctype])
wn.model.docinfo[doc.doctype] = {};
wn.model.docinfo[doc.doctype][doc.name] = r.docinfo;
}
return doclist;
},

View file

@ -193,7 +193,7 @@ wn.request.cleanup = function(opts, r) {
}
if(r.docs) {
r.docs = wn.model.sync(r.docs);
r.docs = wn.model.sync(r);
}
if(r.__messages) {
$.extend(wn._messages, r.__messages);

View file

@ -24,9 +24,8 @@
wn.ui.toolbar.Toolbar = Class.extend({
init: function() {
this.make();
this.make_erpnext();
//this.make_modules();
this.make_file();
this.make_view();
//this.make_actions();
wn.ui.toolbar.recent = new wn.ui.toolbar.RecentDocs();
wn.ui.toolbar.bookmarks = new wn.ui.toolbar.Bookmarks();
@ -72,11 +71,11 @@ wn.ui.toolbar.Toolbar = Class.extend({
$('.navbar-brand').attr('href', "#");
},
make_erpnext: function() {
make_modules: function() {
$('<li class="dropdown">\
<a class="dropdown-toggle" data-toggle="dropdown" href="#"\
title="'+wn._("Modules")+'"\
onclick="return false;">erpnext</a>\
onclick="return false;">'+wn._("Modules")+'</a>\
<ul class="dropdown-menu modules">\
</ul>\
</li>').prependTo('.navbar .nav:first');
@ -135,15 +134,6 @@ wn.ui.toolbar.Toolbar = Class.extend({
</li>');
},
make_view: function() {
$('.navbar .nav:first').append('<li class="dropdown">\
<a class="dropdown-toggle" data-toggle="dropdown" href="#" \
title="'+wn._("View")+'"\
onclick="return false;">'+wn._("View")+'</a>\
<ul class="dropdown-menu" id="navbar-view">\
</ul>\
</li>');
},
// make_actions: function() {
// $('.navbar .nav:first').append('<li class="dropdown">\

View file

@ -74,7 +74,7 @@ wn.views.CommunicationList = Class.extend({
//doc.when = comment_when(this.doc.modified);
doc.when = doc.modified;
if(!doc.content) doc.content = "[no content]";
if(doc.content.indexOf("<br>")== -1 && doc.content.indexOf("<p>")== -1) {
if(!wn.utils.is_html(doc.content)) {
doc.content = doc.content.replace(/\n/g, "<br>");
}
if(!doc.sender) doc.sender = "[unknown sender]";
@ -278,8 +278,7 @@ wn.views.CommunicationComposer = Class.extend({
: [];
var signature = wn.boot.profile.email_signature || "";
if(signature.indexOf("<br>")==-1 && signature.indexOf("<p")==-1
&& signature.indexOf("<img")==-1 && signature.indexOf("<div")==-1) {
if(!wn.utils.is_html(signature)) {
signature = signature.replace(/\n/g, "<br>");
}

View file

@ -96,7 +96,7 @@ wn.views.ListView = Class.extend({
var colspan = "2";
if(in_list(["Int", "Percent"], d.fieldtype)) {
colspan = "1";
} else if(d.fieldtype=="Check" || d.fieldname=="file_list") {
} else if(d.fieldtype=="Check") {
colspan = "1";
} else if(d.fieldname=="subject" || d.fieldname=="title") { // subjects are longer
colspan = "3";

View file

@ -38,9 +38,24 @@ def getdoc(doctype, name, user=None):
if not (doctype and name):
raise Exception, 'doctype and name required!'
doclist = []
# single
doclist = load_single_doc(doctype, name, user or webnotes.session.user)
if not name:
name = doctype
if not webnotes.conn.exists(doctype, name):
return []
try:
doclist = webnotes.bean(doctype, name).doclist
# add file list
set_docinfo(doctype, name)
except Exception, e:
webnotes.errprint(webnotes.utils.getTraceback())
webnotes.msgprint('Did not load.')
raise e
if doclist and not name.startswith('_'):
webnotes.user.update_recent(doctype, name)
webnotes.response['docs'] = doclist
@ -67,50 +82,30 @@ def getdoctype(doctype, with_parent=False, cached_timestamp=None):
webnotes.response['docs'] = doclist
def load_single_doc(dt, dn, user):
"""load doc and call onload methods"""
# ----- REPLACE BY webnotes.client.get ------
def set_docinfo(doctype, name):
webnotes.response["docinfo"] = {
"attachments": add_attachments(doctype, name),
"comments": add_comments(doctype, name),
"assignments": add_assignments(doctype, name)
}
if not dn: dn = dt
if not webnotes.conn.exists(dt, dn):
return None
try:
dl = webnotes.bean(dt, dn).doclist
# add file list
add_file_list(dt, dn, dl)
add_comments(dt, dn, dl)
add_assignments(dt, dn, dl)
except Exception, e:
webnotes.errprint(webnotes.utils.getTraceback())
webnotes.msgprint('Did not load.')
raise e
if dl and not dn.startswith('_'):
webnotes.user.update_recent(dt, dn)
return dl
def add_file_list(dt, dn, dl):
file_list = {}
def add_attachments(dt, dn):
attachments = {}
for f in webnotes.conn.sql("""select name, file_name, file_url from
`tabFile Data` where attached_to_name=%s and attached_to_doctype=%s""",
(dn, dt), as_dict=True):
file_list[f.file_url or f.file_name] = f.name
attachments[f.file_url or f.file_name] = f.name
if file_list:
dl[0].file_list = json.dumps(file_list)
return attachments
def add_comments(dt, dn, dl, limit=20):
def add_comments(dt, dn, limit=20):
cl = webnotes.conn.sql("""select name, comment, comment_by, creation from `tabComment`
where comment_doctype=%s and comment_docname=%s
order by creation desc limit %s""" % ('%s','%s', limit), (dt, dn), as_dict=1)
dl[0].fields["__comments"] = json.dumps(cl)
return cl
def add_assignments(dt, dn, dl):
def add_assignments(dt, dn):
cl = webnotes.conn.sql_list("""select owner from `tabToDo`
where reference_type=%(doctype)s and reference_name=%(name)s
order by modified desc limit 5""", {
@ -118,4 +113,4 @@ def add_assignments(dt, dn, dl):
"name": dn
})
dl[0].fields["__assign_to"] = json.dumps(cl)
return cl

View file

@ -58,8 +58,8 @@ def cancel(doctype=None, name=None):
raise e
def send_updated_docs(wrapper):
from load import add_file_list
add_file_list(wrapper.doc.doctype, wrapper.doc.name, wrapper.doclist)
from load import set_docinfo
set_docinfo(wrapper.doc.doctype, wrapper.doc.name)
webnotes.response['main_doc_name'] = wrapper.doc.name
webnotes.response['doctype'] = wrapper.doc.doctype