diff --git a/frappe/core/doctype/comment/comment.json b/frappe/core/doctype/comment/comment.json
index 66a2736f9e..0fdff9355d 100644
--- a/frappe/core/doctype/comment/comment.json
+++ b/frappe/core/doctype/comment/comment.json
@@ -16,6 +16,12 @@
"reqd": 1,
"search_index": 0
},
+ {
+ "fieldname": "comment_type",
+ "fieldtype": "Data",
+ "label": "Comment Type",
+ "permlevel": 0
+ },
{
"fieldname": "comment_by",
"fieldtype": "Data",
@@ -100,7 +106,7 @@
"icon": "icon-comments",
"idx": 1,
"issingle": 0,
- "modified": "2014-07-14 12:14:08.315217",
+ "modified": "2014-08-11 05:43:35.647132",
"modified_by": "Administrator",
"module": "Core",
"name": "Comment",
diff --git a/frappe/core/doctype/comment/test_records.json b/frappe/core/doctype/comment/test_records.json
new file mode 100644
index 0000000000..2c213721dc
--- /dev/null
+++ b/frappe/core/doctype/comment/test_records.json
@@ -0,0 +1,6 @@
+[
+ {
+ "doctype": "Comment",
+ "name": "_Test Comment 1"
+ }
+]
diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json
index 001ff5f121..b68c2e8ec4 100644
--- a/frappe/core/doctype/docfield/docfield.json
+++ b/frappe/core/doctype/docfield/docfield.json
@@ -34,7 +34,7 @@
"label": "Type",
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
- "options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
+ "options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"reqd": 1,
"search_index": 1
@@ -259,7 +259,6 @@
"width": "50px"
},
{
- "description": "Print Width of the field, if the field is a column in a table",
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width",
@@ -305,7 +304,7 @@
"in_dialog": 1,
"issingle": 0,
"istable": 1,
- "modified": "2014-08-05 08:29:06.769568",
+ "modified": "2014-08-11 07:00:52.537012",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py
index 937e47bf0c..2be779b001 100644
--- a/frappe/core/doctype/doctype/doctype.py
+++ b/frappe/core/doctype/doctype/doctype.py
@@ -191,7 +191,7 @@ def validate_fields(fields):
frappe.throw(_("Fieldname {0} appears multiple times in rows {1}").format(fieldname, ", ".join(duplicates)))
def check_illegal_mandatory(d):
- if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd:
+ if (d.fieldtype in no_value_fields) and d.fieldtype!="Table" and d.reqd:
frappe.throw(_("Field {0} of type {1} cannot be mandatory").format(d.label, d.fieldtype))
def check_link_table_options(d):
@@ -228,6 +228,14 @@ def validate_fields(fields):
or (doctype_pointer[0].options!="DocType"):
frappe.throw(_("Options 'Dynamic Link' type of field must point to another Link Field with options as 'DocType'"))
+ def check_fold(fields):
+ for i, f in enumerate(fields):
+ if f.fieldtype=="Fold":
+ prev = fields[i-1]
+ if prev.fieldtype != "Section Break" \
+ or (prev.fieldtype=="Section Break" and not prev.label):
+ frappe.throw(_("Fold must come after labelled Section Break"))
+
for d in fields:
if not d.permlevel: d.permlevel = 0
if not d.fieldname:
@@ -241,6 +249,7 @@ def validate_fields(fields):
check_in_list_view(d)
check_min_items_in_list(fields)
+ check_fold(fields)
def validate_permissions_for_doctype(doctype, for_remove=False):
doctype = frappe.get_doc("DocType", doctype)
diff --git a/frappe/core/doctype/property_setter/property_setter.py b/frappe/core/doctype/property_setter/property_setter.py
index 1d3ed43f3b..b115fba141 100644
--- a/frappe/core/doctype/property_setter/property_setter.py
+++ b/frappe/core/doctype/property_setter/property_setter.py
@@ -28,7 +28,7 @@ class PropertySetter(Document):
return frappe.db.sql("""select fieldname, label, fieldtype
from tabDocField
where parent=%s
- and fieldtype not in ('Section Break', 'Column Break', 'HTML', 'Read Only', 'Table')
+ and fieldtype not in ('Section Break', 'Column Break', 'HTML', 'Read Only', 'Table', 'Fold')
and ifnull(fieldname, '') != ''
order by label asc""", dt, as_dict=1)
diff --git a/frappe/core/doctype/todo/todo.py b/frappe/core/doctype/todo/todo.py
index 4d232546e9..1db7e1dbe6 100644
--- a/frappe/core/doctype/todo/todo.py
+++ b/frappe/core/doctype/todo/todo.py
@@ -9,19 +9,20 @@ from frappe.model.document import Document
class ToDo(Document):
def validate(self):
if self.is_new():
- self.add_comment(frappe._("Assignment Added"))
+ self.add_comment(frappe._("Assigned to {0}").format(self.owner), "Assigned")
else:
cur_status = frappe.db.get_value("ToDo", self.name, "status")
if cur_status != self.status:
- self.add_comment(frappe._("Assignment Status Changed"))
+ self.add_comment(frappe._("Assignment Status Changed"), "Assignment Completed")
- def add_comment(self, text):
+ def add_comment(self, text, comment_type):
if not self.reference_type and self.reference_name:
return
comment = frappe.get_doc({
"doctype":"Comment",
"comment_by": frappe.session.user,
+ "comment_type": comment_type,
"comment_doctype": self.reference_type,
"comment_docname": self.reference_name,
"comment": """
{text}:
diff --git a/frappe/core/page/desktop/desktop.css b/frappe/core/page/desktop/desktop.css
index 084053fe8a..d77a04f3b0 100644
--- a/frappe/core/page/desktop/desktop.css
+++ b/frappe/core/page/desktop/desktop.css
@@ -77,4 +77,6 @@
padding-top: 14px;
padding-bottom: 50px;
margin-bottom: -50px;
+ border: 0px;
+ background-color: transparent;
}
diff --git a/frappe/model/__init__.py b/frappe/model/__init__.py
index 45b42ef38c..f6d3af095f 100644
--- a/frappe/model/__init__.py
+++ b/frappe/model/__init__.py
@@ -7,7 +7,7 @@ import frappe
import json
-no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'Button', 'Image']
+no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'Button', 'Image', 'Fold']
default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus']
integer_docfield_properties = ["reqd", "search_index", "in_list_view", "permlevel", "hidden", "read_only", "ignore_user_permissions", "allow_on_submit", "report_hide", "in_filter", "no_copy", "print_hide"]
diff --git a/frappe/model/document.py b/frappe/model/document.py
index e5dadf958b..530693504c 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -428,9 +428,11 @@ class Document(BaseDocument):
elif self._action=="submit":
self.run_method("on_update")
self.run_method("on_submit")
+ self.add_comment("Submitted")
elif self._action=="cancel":
self.run_method("on_cancel")
self.check_no_back_links_exist()
+ self.add_comment("Cancelled")
elif self._action=="update_after_submit":
self.run_method("on_update_after_submit")
@@ -564,3 +566,13 @@ class Document(BaseDocument):
def get_url(self):
return "/desk#Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name)
+
+ def add_comment(self, comment_type, text=None):
+ comment = frappe.get_doc({
+ "doctype":"Comment",
+ "comment_by": frappe.session.user,
+ "comment_type": comment_type,
+ "comment_doctype": self.doctype,
+ "comment_docname": self.name,
+ "comment": text or comment_type
+ }).insert(ignore_permissions=True)
diff --git a/frappe/public/css/appframe.css b/frappe/public/css/appframe.css
index c2c17cad42..e4c694526a 100644
--- a/frappe/public/css/appframe.css
+++ b/frappe/public/css/appframe.css
@@ -8,17 +8,11 @@
.appframe-wrapper {
background-color: #fff;
min-height: 400px;
- box-shadow: 1px 0px 1px rgba(0,0,0,0.4);
+ /*box-shadow: 1px 0px 1px rgba(0,0,0,0.4);*/
}
.appframe-titlebar {
- border-bottom: 1px solid #ddd;
-}
-
-.appframe-footer {
- border-top: 1px solid #ddd;
- /*background-color: rgba(255, 255, 255, 0.9);*/
- background-color: #f9f9f9;
+ border-bottom: 1px solid #c7c7c7;
}
.appframe-titlebar, .appframe-iconbar, .appframe-form, .appframe-primary-actions {
@@ -26,13 +20,17 @@
background-color: #f9f9f9;
}
+.appframe-primary-actions {
+ border-bottom: 1px solid #c7c7c7;
+}
+
.appframe-primary-actions .btn {
margin: 10px;
margin-left: 0px;
}
.appframe-iconbar {
- border-bottom: 1px solid #ddd;
+ border-bottom: 1px solid #c7c7c7;
}
.titlebar-item {
@@ -148,7 +146,7 @@ h2.titlebar-left-item {
}
.iconbar-4 {
- border-left: 1px solid #ddd;
+ border-left: 1px solid #c7c7c7;
padding-left: 4px;
}
@@ -185,11 +183,6 @@ h2.titlebar-left-item {
color: orange;
}
-
-.appframe-footer {
- padding-top: 15px;
-}
-
.workflow-button-area {
margin-bottom: 15px;
}
diff --git a/frappe/public/css/avatar.css b/frappe/public/css/avatar.css
index d74a9b6c07..b48c5f9807 100644
--- a/frappe/public/css/avatar.css
+++ b/frappe/public/css/avatar.css
@@ -1,7 +1,7 @@
.avatar {
display: inline-block;
vertical-align: middle;
- border-radius: 50%;
+ border-radius: 5px;
overflow: hidden;
background-color: #ddd;
border: 1px solid #eee;
diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css
index d70f42a655..83138bf4cb 100644
--- a/frappe/public/css/desk.css
+++ b/frappe/public/css/desk.css
@@ -66,8 +66,16 @@ div#freeze {
text-align: center;
}
-/* listing */
+.app-page {
+ border: 1px solid #c7c7c7;
+ border-radius: 4px;
+ margin-top: 15px;
+ padding: 0px;
+ overflow: hidden;
+}
+
+/* listing */
.show_filters {
padding-top: 15px;
padding-bottom: 15px;
@@ -122,6 +130,13 @@ div#freeze {
/*margin-top: -15px;*/
}
+.form-page-header {
+ border-top: 1px solid #eee;
+ margin: 15px -15px -15px -15px;
+ padding: 10px 15px;
+ background-color: #f9f9f9;
+}
+
.form-control {
padding: 6px 8px;
}
@@ -262,6 +277,43 @@ div#freeze {
}
/* form */
+.comment-connector {
+ height: 30px;
+ margin-left: 70px;
+ border-left: 1px solid #d7d7d7;
+}
+
+.comment-body {
+ border-left: 1px solid #d7d7d7;
+ padding: 5px 15px 15px 30px;
+}
+
+.comment-body p {
+ margin-bottom: 5px;
+}
+
+.comment-icon {
+ margin-right: -14px !important;
+ margin-left: 15px;
+ z-index: 1;
+}
+
+.icon-timeline {
+ color: #fff;
+ height: 29px;
+ width: 29px;
+ padding: 7px 9px;
+ border-radius: 50%;
+ background-color: #d7d7d7;
+ text-align: center;
+ display: inline-block;
+ float: left;
+}
+
+.comment {
+ margin-top: 0px;
+}
+
.frappe-editor {
cursor: text;
}
@@ -295,7 +347,8 @@ ul.linked-with-list li {
.grid-heading-row {
padding: 8px 15px;
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #c7c7c7;
+ background-color: #f9f9f9;
font-weight: bold;
}
@@ -303,7 +356,7 @@ ul.linked-with-list li {
padding-bottom: 5px;
margin-bottom: 5px;
margin-top: 8px;
- border-bottom: 1px solid #dddddd;
+ border-bottom: 1px solid #c7c7c7;
}
.rows .grid-row .data-row, .rows .grid-row .panel-heading {
@@ -403,6 +456,7 @@ ul.linked-with-list li {
margin-bottom: 7px;
}
+
/* hack */
.ui-datepicker { z-index: 9999999 !important; }
.ui-autocomplete {
diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js
index 36549fcedc..21e7510964 100644
--- a/frappe/public/js/frappe/desk.js
+++ b/frappe/public/js/frappe/desk.js
@@ -35,8 +35,7 @@ frappe.Application = Class.extend({
// load boot info
this.load_bootinfo();
- // page container
- this.make_page_container();
+ if(user!="Guest") this.set_user_display_settings();
// navbar
this.make_nav_bar();
@@ -44,8 +43,6 @@ frappe.Application = Class.extend({
// favicon
this.set_favicon();
- if(user!="Guest") this.set_user_display_settings();
-
this.setup_keyboard_shortcuts();
// control panel startup code
@@ -58,10 +55,14 @@ frappe.Application = Class.extend({
localStorage.removeItem("session_lost_route");
}
- // route to home page
- frappe.route();
}
+ // page container
+ this.make_page_container();
+
+ // route to home page
+ frappe.route();
+
// trigger app startup
$(document).trigger('startup');
@@ -176,7 +177,7 @@ frappe.Application = Class.extend({
make_nav_bar: function() {
// toolbar
if(frappe.boot) {
- frappe.container.frappe_toolbar = new frappe.ui.toolbar.Toolbar();
+ frappe.frappe_toolbar = new frappe.ui.toolbar.Toolbar();
}
},
logout: function() {
diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js
index cac0bc1193..f4523235ef 100644
--- a/frappe/public/js/frappe/dom.js
+++ b/frappe/public/js/frappe/dom.js
@@ -174,52 +174,6 @@ frappe.get_shade = function(color, factor) {
+ get_hex(get_int(color.substr(4,2)) + factor)
}
-frappe.get_gradient_css = function(col, diff) {
- if(!diff) diff = 10
- var col1 = frappe.get_shade(col, diff);
- var col2 = frappe.get_shade(col, -diff);
- return "\nbackground-color: " + col + " !important;"
- +"\nbackground: -moz-linear-gradient(top, #"+col1+" 0%, #"+col2+" 99%) !important;"
- +"\nbackground:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#"+col1+"), color-stop(99%,#"+col2+")) !important;"
- +"\nbackground:-webkit-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-ms-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:linear-gradient(top, #"+col1+" 0%,#%"+col2+" 99%) !important;"
- +"\nfilter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#"+col1+"', endColorstr='#"+col1+"',GradientType=0 ) !important;"
-}
-
-$.fn.gradientify = function(col) {
- if(!col) col = this.css("background-color");
- var col1 = frappe.get_shade(col, 1.05);
- var col2 = frappe.get_shade(col, 0.95);
-
- this.css({
- "background": "-moz-linear-gradient(top, #"+col1+" 0%, #"+col2+" 99%)"
- });
- this.css({
- "background": "-webkit-gradient(linear, left top, left bottom, color-stop(0%,#"+col1+"), color-stop(99%,#"+col2+"))"
- });
- this.css({
- "background": "-webkit-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%)"
- });
- this.css({
- "background": "-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "-ms-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "linear-gradient(top, #"+col1+" 0%,#%"+col2+" 99%);"
- });
- this.css({
- "filter": "progid:DXImageTransform.Microsoft.gradient( startColorstr='#"+col1+"', endColorstr='#"+col1+"',GradientType=0 )"
- });
-}
-
frappe.get_cookie = function(c) {
var clist = (document.cookie+'').split(';');
var cookies = {};
@@ -265,21 +219,9 @@ frappe.dom.set_box_shadow = function(ele, spread) {
return $(this);
}
$.fn.set_working = function() {
- var ele = this.get(0);
- $(ele).prop('disabled', true);
- if(ele.loading_img) {
- $(ele.loading_img).toggle(true);
- } else {
- ele.loading_img = $('

')
- .insertAfter(ele);
- }
+ this.prop('disabled', true);
}
$.fn.done_working = function() {
- var ele = this.get(0);
- $(ele).prop('disabled', false);
- if(ele.loading_img) {
- $(ele.loading_img).toggle(false);
- };
+ this.prop('disabled', false);
}
})(jQuery);
diff --git a/frappe/public/js/frappe/form/comments.js b/frappe/public/js/frappe/form/comments.js
index 265ce50dff..1c78aa885d 100644
--- a/frappe/public/js/frappe/form/comments.js
+++ b/frappe/public/js/frappe/form/comments.js
@@ -9,25 +9,30 @@ frappe.ui.form.Comments = Class.extend({
make: function() {
var me = this;
this.wrapper =this.parent;
- this.row = $("
").appendTo(this.parent);
- this.input = $('
\
-
')
- .appendTo(this.row)
- .find("textarea");
- this.button = $('
\
- \
-
')
- .appendTo(this.row)
- .find("button")
+ $('').appendTo(this.parent);
+ this.list = $('')
+ .appendTo(this.parent);
+
+ this.row = $(repl('', {image: frappe.user_info(user).image,
+ fullname: user_fullname})).appendTo(this.parent);
+
+ this.input = this.row.find(".form-control");
+ this.button = this.row.find(".btn-go")
.click(function() {
me.add_comment(this);
});
- this.list = $('')
- .appendTo(this.parent);
- },
- get_comments: function() {
- return this.frm.get_docinfo().comments;
},
refresh: function() {
var me = this;
@@ -37,7 +42,10 @@ frappe.ui.form.Comments = Class.extend({
}
this.wrapper.toggle(true);
this.list.empty();
- var comments = this.get_comments();
+
+ comments = [{"comment": "Created", "comment_type": "Created",
+ "comment_by": this.frm.doc.owner, "creation": this.frm.doc.creation}].concat(this.get_comments());
+
$.each(comments, function(i, c) {
if(frappe.model.can_delete("Comment")) {
c["delete"] = '
×';
@@ -47,15 +55,52 @@ frappe.ui.form.Comments = Class.extend({
c.image = frappe.user_info(c.comment_by).image || frappe.get_gravatar(c.comment_by);
c.comment_on = dateutil.comment_when(c.creation);
c.fullname = frappe.user_info(c.comment_by).fullname;
- c.comment = frappe.markdown(c.comment);
- $(repl('