浏览代码

Merge pull request #562 from rmehta/develop

Various UI Bug Fixes
version-14
Anand Doshi 11 年前
父节点
当前提交
8cd8c6f9c3
共有 25 个文件被更改,包括 289 次插入446 次删除
  1. +4
    -2
      frappe/core/doctype/customize_form/customize_form.js
  2. +13
    -260
      frappe/core/doctype/system_settings/system_settings.json
  3. +22
    -0
      frappe/core/doctype/workflow/workflow.py
  4. +5
    -3
      frappe/core/doctype/workflow_document_state/workflow_document_state.json
  5. +1
    -1
      frappe/public/css/appframe.css
  6. 二进制
      frappe/public/images/help/style-settings-help.png
  7. +26
    -25
      frappe/public/js/frappe/misc/number_format.js
  8. +7
    -5
      frappe/public/js/frappe/misc/pretty_date.js
  9. +2
    -2
      frappe/public/js/frappe/ui/appframe.js
  10. +18
    -9
      frappe/public/js/frappe/ui/filters.js
  11. +31
    -0
      frappe/public/js/frappe/ui/listing.js
  12. +0
    -39
      frappe/public/js/frappe/views/doclistview.js
  13. +1
    -3
      frappe/public/js/frappe/views/grid_report.js
  14. +1
    -0
      frappe/public/js/frappe/views/listview.js
  15. +0
    -1
      frappe/public/js/frappe/views/reportview.js
  16. +6
    -0
      frappe/public/js/legacy/datetime.js
  17. +1
    -2
      frappe/templates/base.html
  18. +26
    -37
      frappe/templates/pages/style_settings.css
  19. +15
    -16
      frappe/templates/pages/style_settings.py
  20. +9
    -8
      frappe/utils/dateutils.py
  21. +1
    -0
      frappe/website/css/website.css
  22. +5
    -3
      frappe/website/doctype/style_settings/style_settings.js
  23. +65
    -21
      frappe/website/doctype/style_settings/style_settings.json
  24. +3
    -8
      frappe/website/doctype/style_settings/style_settings.py
  25. +27
    -1
      frappe/website/doctype/web_page/web_page.py

+ 4
- 2
frappe/core/doctype/customize_form/customize_form.js 查看文件

@@ -73,8 +73,10 @@ frappe.ui.form.on("Customize Form", "refresh", function(frm) {
// }

if(frappe.route_options) {
frappe.model.set_value("Customize Form", null, "doc_type", frappe.route_options.doctype)
frappe.route_options = null;
setTimeout(function() {
frm.set_value("doc_type", frappe.route_options.doctype);
frappe.route_options = null;
}, 1000);
}
});



+ 13
- 260
frappe/core/doctype/system_settings/system_settings.json 查看文件

@@ -1,339 +1,92 @@
{
"_last_update": null,
"_user_tags": null,
"allow_attach": null,
"allow_copy": null,
"allow_email": null,
"allow_import": null,
"allow_print": null,
"allow_rename": null,
"allow_trash": null,
"autoname": null,
"change_log": null,
"client_script": null,
"client_script_core": null,
"client_string": null,
"colour": null,
"creation": "2014-04-17 16:53:52.640856",
"custom": null,
"default_print_format": null,
"description": null,
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"dt_template": null,
"fields": [
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "localization",
"fieldtype": "Section Break",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Localization",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "language",
"fieldtype": "Select",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "Language",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Loading...",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": 1,
"search_index": 0,
"set_only_once": null,
"trigger": null,
"width": null
"search_index": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "time_zone",
"fieldtype": "Select",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Time Zone",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": 1,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"reqd": 1
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "date_and_number_format",
"fieldtype": "Section Break",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Date and Number Format",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "date_format",
"fieldtype": "Select",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Date Format",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy",
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\ndd.mm.yyyy\nmm/dd/yyyy\nmm-dd-yyyy",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": 1,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"reqd": 1
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "number_format",
"fieldtype": "Select",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Number Format",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "#,###.##\n#.###,##\n# ###.##\n#,###.###\n#,##,###.##\n#.###\n#,###",
"options": "#,###.##\n#.###,##\n# ###.##\n# ###,##\n#,###.###\n#,##,###.##\n#.###\n#,###",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": 1,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"reqd": 1
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "float_precision",
"fieldtype": "Select",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Float Precision",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "\n2\n3\n4\n5\n6",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "security",
"fieldtype": "Section Break",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Security",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": "06:00",
"depends_on": null,
"description": "Session Expiry in Hours e.g. 06:00",
"fieldname": "session_expiry",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Session Expiry",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
}
],
"hide_heading": null,
"hide_toolbar": null,
"icon": "icon-cog",
"idx": null,
"in_create": null,
"in_dialog": null,
"is_submittable": null,
"is_transaction_doc": null,
"issingle": 1,
"istable": null,
"max_attachments": null,
"menu_index": null,
"modified": "2014-04-17 17:52:27.046530",
"modified": "2014-05-27 07:58:24.700595",
"modified_by": "Administrator",
"module": "Core",
"name": "System Settings",
"name_case": "",
"owner": "Administrator",
"parent": null,
"parent_node": null,
"parentfield": null,
"parenttype": null,
"permissions": [
{
"amend": null,
"cancel": null,
"create": 1,
"delete": null,
"email": null,
"export": null,
"import": null,
"match": null,
"permlevel": 0,
"print": null,
"read": 1,
"report": null,
"restrict": null,
"restricted": null,
"role": "System Manager",
"submit": null,
"write": 1
}
],
"plugin": null,
"print_outline": null,
"read_only": null,
"read_only_onload": null,
"search_fields": null,
"section_style": null,
"server_code": null,
"server_code_compiled": null,
"server_code_core": null,
"server_code_error": null,
"show_in_menu": null,
"smallicon": null,
"subject": null,
"tag_fields": null,
"title_field": null,
"use_template": null,
"version": null
]
}

+ 22
- 0
frappe/core/doctype/workflow/workflow.py 查看文件

@@ -13,6 +13,7 @@ class Workflow(Document):
self.set_active()
self.create_custom_field_for_workflow_state()
self.update_default_workflow_status()
self.validate_docstatus()

def on_update(self):
frappe.clear_cache(doctype=self.document_type)
@@ -46,6 +47,27 @@ class Workflow(Document):
'%s', self.workflow_state_field, "%s"), (d.state, d.doc_status))
docstatus_map[d.doc_status] = d.state

def validate_docstatus(self):
def get_state(state):
for s in self.workflow_document_states:
if s.state==state:
return s

frappe.throw(frappe._("{0} not a valid State").format(state))

for t in self.workflow_transitions:
state = get_state(t.state)
next_state = get_state(t.next_state)

if state.doc_status=="2":
frappe.throw(frappe._("Cannot change state of Cancelled Document. Transition row {0}").format(t.idx))

if state.doc_status=="1" and next_state.doc_status=="0":
frappe.throw(frappe._("Submitted Document cannot be converted back to draft. Transition row {0}").format(t.idx))

if state.doc_status=="0" and next_state.doc_status=="2":
frappe.throw(frappe._("Cannot cancel before submitting. See Transition {0}").format(t.idx))

def set_active(self):
if int(self.is_active or 0):
# clear all other


+ 5
- 3
frappe/core/doctype/workflow_document_state/workflow_document_state.json 查看文件

@@ -1,6 +1,6 @@
{
"allow_import": 1,
"creation": "2013-02-22 01:27:36.000000",
"creation": "2013-02-22 01:27:36",
"description": "Represents the states allowed in one document and role assigned to change the state.",
"docstatus": 0,
"doctype": "DocType",
@@ -18,6 +18,7 @@
"width": "160px"
},
{
"description": "0 - Draft; 1 - Submitted; 2 - Cancelled",
"fieldname": "doc_status",
"fieldtype": "Select",
"in_list_view": 1,
@@ -65,9 +66,10 @@
],
"idx": 1,
"istable": 1,
"modified": "2013-12-20 19:21:55.000000",
"modified": "2014-05-27 06:35:01.070157",
"modified_by": "Administrator",
"module": "Core",
"name": "Workflow Document State",
"owner": "Administrator"
"owner": "Administrator",
"permissions": []
}

+ 1
- 1
frappe/public/css/appframe.css 查看文件

@@ -38,7 +38,7 @@
}

.titlebar-item.text-right {
margin-top: 5px;
margin-top: 3px;
}

.titlebar-left-item {


二进制
frappe/public/images/help/style-settings-help.png 查看文件

之前 之后
宽度: 1158  |  高度: 798  |  大小: 151 KiB

+ 26
- 25
frappe/public/js/frappe/misc/number_format.js 查看文件

@@ -3,9 +3,9 @@

if(!window.frappe) window.frappe = {};

function flt(v, decimals, number_format) {
function flt(v, decimals, number_format) {
if(v==null || v=='')return 0;
if(typeof v!=="number") {
v = v + "";

@@ -20,27 +20,27 @@ function flt(v, decimals, number_format) {
if(isNaN(v))
v=0;
}
if(decimals!=null)
return _round(v, decimals);
return v;
}

function cint(v, def) {
if(v===true)
function cint(v, def) {
if(v===true)
return 1;
if(v===false)
return 0;
v=v+'';
if(v!=="0")v=lstrip(v, ['0']);
v=parseInt(v);
if(v!=="0")v=lstrip(v, ['0']);
v=parseInt(v);
if(isNaN(v))v=def===undefined?0:def;
return v;
return v;
}

function strip_number_groups(v, number_format) {
if(!number_format) number_format = get_number_format();
// strip groups (,)
if(get_number_format_info(number_format).group_sep==".") {
v = v.replace(/\./g,'');
@@ -50,7 +50,7 @@ function strip_number_groups(v, number_format) {
} else {
v=v.replace(/,/g,'');
}
return v;
}

@@ -59,32 +59,33 @@ frappe.number_format_info = {
"#,###.##": {decimal_str:".", group_sep:",", precision:2},
"#.###,##": {decimal_str:",", group_sep:".", precision:2},
"# ###.##": {decimal_str:".", group_sep:" ", precision:2},
"# ###,##": {decimal_str:",", group_sep:" ", precision:2},
"#,###.###": {decimal_str:".", group_sep:",", precision:3},
"#,##,###.##": {decimal_str:".", group_sep:",", precision:2},
"#.###": {decimal_str:"", group_sep:".", precision:0},
"#,###": {decimal_str:"", group_sep:",", precision:0},
}

window.format_number = function(v, format, decimals){
window.format_number = function(v, format, decimals){
if (!format) {
format = get_number_format();
if(decimals == null) decimals = cint(frappe.defaults.get_default("float_precision")) || 3;
}

info = get_number_format_info(format);
//Fix the decimal first, toFixed will auto fill trailing zero.
decimals = decimals || info.precision;
v = flt(v, decimals, format);

if(v<0) var is_negative = true;
if(v<0) var is_negative = true;
v = Math.abs(v);
v = v.toFixed(decimals);

var part = v.split('.');
// get group position and parts
var group_position = info.group_sep ? 3 : 0;

@@ -92,14 +93,14 @@ window.format_number = function(v, format, decimals){
var integer = part[0];
var str = '';
var offset = integer.length % group_position;
for (var i=integer.length; i>=0; i--) {
for (var i=integer.length; i>=0; i--) {
var l = replace_all(str, info.group_sep, "").length;
if(format=="#,##,###.##" && str.indexOf(",")!=-1) { // INR
group_position = 2;
l += 1;
}
str += integer.charAt(i);
str += integer.charAt(i);

if (l && !((l+1) % group_position) && i!=0 ) {
str += info.group_sep;
@@ -110,10 +111,10 @@ window.format_number = function(v, format, decimals){
if(part[0]+""=="") {
part[0]="0";
}
// join decimal
part[1] = part[1] ? (info.decimal_str + part[1]) : "";
// join
return (is_negative ? "-" : "") + part[0] + part[1];
};
@@ -150,13 +151,13 @@ function get_number_format(currency) {
|| frappe.model.get_value("Currency", frappe.boot.sysdefaults.currency, "number_format")
|| "#,###.##";
}
var number_format;
if(currency && frappe.boot) {
number_format = frappe.model.get_value("Currency", currency,
number_format = frappe.model.get_value("Currency", currency,
"number_format");
}
return number_format || global_number_format;
}

@@ -205,4 +206,4 @@ function in_list(list, item) {
for(var i=0, j=list.length; i<j; i++)
if(list[i]==item) return true;
return false;
}
}

+ 7
- 5
frappe/public/js/frappe/misc/pretty_date.js 查看文件

@@ -3,13 +3,13 @@ function prettyDate(time){
var date = time;
if(typeof(time)=="string")
date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ").replace(/\.[0-9]*/, ""));
var diff = (((new Date()).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 )
return '';
return when = day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
@@ -21,12 +21,14 @@ function prettyDate(time){
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
day_diff < 365 && Math.ceil( day_diff / 30) + " months ago" ||
"> " + Math.floor( day_diff / 365 ) + " year(s) ago";
}


var comment_when = function(datetime) {
return '<span class="frappe-timestamp" data-timestamp="'+datetime+'">' + prettyDate(datetime) + '</span>';
return '<span class="frappe-timestamp" data-timestamp="'+datetime
+'" title="'+datetime+'">'
+ prettyDate(datetime) + '</span>';
};

frappe.provide("frappe.datetime");


+ 2
- 2
frappe/public/js/frappe/ui/appframe.js 查看文件

@@ -16,7 +16,7 @@ frappe.ui.AppFrame = Class.extend({
<span class="title-text"></span>\
</span>').appendTo($center);

this.$sub_title_area = $('<div class="title-sub"></div>')
this.$sub_title_area = $('<div class="title-sub hide"></div>')
.appendTo($center);

this.setup_iconbar();
@@ -53,7 +53,7 @@ frappe.ui.AppFrame = Class.extend({

set_title_sub: function(txt) {
// strip icon
this.$sub_title_area.html(txt);
this.$sub_title_area.html(txt).toggleClass("hide", !!!txt);
},

set_title_left: function(click) {


+ 18
- 9
frappe/public/js/frappe/ui/filters.js 查看文件

@@ -21,8 +21,10 @@ frappe.ui.FilterList = Class.extend({

show_filters: function() {
this.$w.find('.show_filters').toggle();
if(!this.filters.length)
if(!this.filters.length) {
this.add_filter();
this.filters[0].$w.find(".filter_field input").focus();
}
},

clear_filters: function() {
@@ -116,7 +118,9 @@ frappe.ui.Filter = Class.extend({
me.set_field(doctype, fieldname);
}
});
this.fieldselect.set_value(this.doctype, this.fieldname);
if(this.fieldname) {
this.fieldselect.set_value(this.doctype, this.fieldname);
}
},
set_events: function() {
var me = this;
@@ -141,14 +145,19 @@ frappe.ui.Filter = Class.extend({

// add help for "in" codition
me.$w.find('.condition').change(function() {
if($(this).val()=='in') {
me.set_field(me.field.df.parent, me.field.df.fieldname, 'Data');
if(!me.field.desc_area)
me.field.desc_area = $a(me.field.wrapper, 'span', 'help', null,
'values separated by comma');
var condition = $(this).val();
if(in_list(["in", "like"], condition)) {
me.set_field(me.field.df.parent, me.field.df.fieldname, 'Data', condition);
if(!me.field.desc_area) {
me.field.desc_area = $('<div class="text-muted small">').appendTo(me.field.wrapper);
}
// set description
me.field.desc_area.html((condition==="in"
? __("values separated by commas")
: __("use % as wildcard"))+'</div>');
} else {
me.set_field(me.field.df.parent, me.field.df.fieldname, null,
me.$w.find('.condition').val());
condition);
}
});

@@ -300,7 +309,7 @@ frappe.ui.FieldSelect = Class.extend({
source: me.options,
minLength: 0,
focus: function(event, ui) {
me.$select.val(ui.item.label);
ui.item && me.$select.val(ui.item.label);
return false;
},
select: function(event, ui) {


+ 31
- 0
frappe/public/js/frappe/ui/listing.js 查看文件

@@ -64,6 +64,20 @@ frappe.ui.Listing = Class.extend({
$.extend(this, this.opts);

$(this.parent).html(repl('\
<div class="show-docstatus hide" style="min-height: 40px;">\
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\
<input type="checkbox" data-docstatus="2">\
<span class="text-muted small">'+__('Cancelled')+'</span>\
</label></div></div>\
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\
<input type="checkbox" data-docstatus="1" checked="checked">\
<span class="text-muted small">'+__('Submitted')+'</span>\
</label></div></div>\
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\
<input type="checkbox" data-docstatus="0" checked="checked">\
<span class="text-muted small">'+__('Drafts')+'</span>\
</label></div></div>\
</div>\
<div class="frappe-list">\
<h3 class="title hide">%(title)s</h3>\
\
@@ -120,6 +134,7 @@ frappe.ui.Listing = Class.extend({
if(this.show_filters) {
this.make_filters();
}
this.setup_docstatus_filter();
},
add_button: function(label, click, icon) {
if(this.appframe) {
@@ -213,6 +228,17 @@ frappe.ui.Listing = Class.extend({
});
},

setup_docstatus_filter: function() {
var me = this;
this.can_submit = frappe.model.is_submittable(me.doctype);
if(this.can_submit) {
$(this.parent).find('.show-docstatus').removeClass('hide');
$(this.parent).find('.show-docstatus input').click(function() {
me.run();
})
}
},

clear: function() {
this.data = [];
this.$w.find('.result-list').empty();
@@ -263,6 +289,11 @@ frappe.ui.Listing = Class.extend({
}
}

args.docstatus = this.can_submit ? $.map($(this.parent).find('.show-docstatus :checked'),
function(inp) {
return $(inp).attr('data-docstatus');
}) : []

// append user-defined arguments
if(this.args)
$.extend(args, this.args)


+ 0
- 39
frappe/public/js/frappe/views/doclistview.js 查看文件

@@ -57,25 +57,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
<div class="help">'+__('Loading')+'...</div></div>')
.appendTo(this.$page.find(".layout-main-section"));

$('<div class="show-docstatus hide side-panel">\
<h5 class="text-muted">Show</h5>\
<div class="side-panel-body">\
<div class="checkbox"><label>\
<input type="checkbox" data-docstatus="0" checked="checked">\
<span class="text-muted">'+__('Drafts')+'</span>\
</label></div>\
<div class="checkbox"><label>\
<input type="checkbox" data-docstatus="1" checked="checked">\
<span class="text-muted">'+__('Submitted')+'</span>\
</label></div>\
<div class="checkbox"><label>\
<input type="checkbox" data-docstatus="2">\
<span class="text-muted">'+__('Cancelled')+'</span>\
</label></div>\
</div>\
</div>')
.appendTo(this.$page.find(".layout-side-section"));

this.$page.find(".layout-main-section")
.addClass("listview-main-section")
.parent().css({"margin-top":"-15px"});
@@ -93,7 +74,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.meta = locals.DocType[this.doctype];
this.$page.find('.frappe-list-area').empty(),
this.setup_listview();
this.setup_docstatus_filter();
this.init_list(false);
this.init_stats();
this.init_minbar();
@@ -149,19 +129,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.appframe.add_help_button(this.meta.description);
}
},
setup_docstatus_filter: function() {
var me = this;
this.can_submit = $.map(locals.DocPerm || [], function(d) {
if(d.parent==me.meta.name && d.submit) return 1
else return null;
}).length;
if(this.can_submit) {
this.$page.find('.show-docstatus').removeClass('hide');
this.$page.find('.show-docstatus input').click(function() {
me.run();
})
}
},
setup_listview: function() {
this.listview = frappe.views.get_listview(this.doctype, this);
this.wrapper = this.$page.find('.frappe-list-area');
@@ -252,16 +219,10 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.listview.render(row, data, this);
},
get_args: function() {
var docstatus_list = this.can_submit ? $.map(this.$page.find('.show-docstatus :checked'),
function(inp) {
return $(inp).attr('data-docstatus');
}) : []

var args = {
doctype: this.doctype,
fields: this.listview.fields,
filters: this.filter_list.get_filters(),
docstatus: docstatus_list,
order_by: this.listview.order_by || undefined,
group_by: this.listview.group_by || undefined,
}


+ 1
- 3
frappe/public/js/frappe/views/grid_report.js 查看文件

@@ -374,11 +374,9 @@ frappe.views.GridReport = Class.extend({
$('<div style="text-align: right;"> \
<div class="processing" style="background-color: #fec; display: none; \
float: left; margin: 2px">Updated! </div> \
<a href="#" class="grid-report-export"> \
<i class="icon icon-download-alt"></i> Export</a> \
</div>').appendTo(this.wrapper);

this.wrapper.find(".grid-report-export").click(function() { return me.export(); });
this.appframe.add_primary_action(__("Export"), function() { return me.export(); }, "icon-download");

// grid wrapper
this.grid_wrapper = $("<div style='height: 500px; border: 1px solid #aaa; \


+ 1
- 0
frappe/public/js/frappe/views/listview.js 查看文件

@@ -246,6 +246,7 @@ frappe.views.ListView = Class.extend({
var col = $("<div class='col'>")
.appendTo(body)
.addClass("col-sm-" + cint(colspan))
.addClass("col-xs-" + (cint(colspan) + 2))
.css({
"white-space": "nowrap",
"text-overflow": "ellipsis",


+ 0
- 1
frappe/public/js/frappe/views/reportview.js 查看文件

@@ -171,7 +171,6 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
fields: $.map(this.columns, function(v) { return me.get_full_column_name(v) }),
order_by: this.get_order_by(),
filters: this.filter_list.get_filters(),
docstatus: ['0','1','2'],
with_childnames: 1
}
},


+ 6
- 0
frappe/public/js/legacy/datetime.js 查看文件

@@ -128,6 +128,8 @@ frappe.datetime = {
val = d[2]+'-'+d[1]+'-'+d[0] + time_str;
else if(user_fmt=='dd/mm/yyyy')
val = d[2]+'/'+d[1]+'/'+d[0] + time_str;
else if(user_fmt=='dd.mm.yyyy')
val = d[2]+'.'+d[1]+'.'+d[0] + time_str;
else if(user_fmt=='yyyy-mm-dd')
val = d[0]+'-'+d[1]+'-'+d[2] + time_str;
else if(user_fmt=='mm/dd/yyyy')
@@ -162,6 +164,10 @@ frappe.datetime = {
var d = d.split('/');
var val = d[2]+'-'+d[1]+'-'+d[0];
}
else if(user_fmt=='dd.mm.yyyy') {
var d = d.split('.');
var val = d[2]+'-'+d[1]+'-'+d[0];
}
else if(user_fmt=='yyyy-mm-dd') {
var val = d;
}


+ 1
- 2
frappe/templates/base.html 查看文件

@@ -1,7 +1,6 @@
<!DOCTYPE html>
<!--
Built on Frappe.io. Free and Open Source Framework for the Web.
https://frappe.io/apps/frappe
Built on Frappe.io. Free and Open Source Framework for the Web. https://frappe.io/
-->
<html lang="en">
<head>


+ 26
- 37
frappe/templates/pages/style_settings.css 查看文件

@@ -29,10 +29,6 @@ body {
}
{% endif %}

div.outer {
background-color: #{{ doc.page_background }};
}

{% if doc.google_web_font_for_heading or doc.heading_font %}h1, h2, h3, h4, h5 {
font-family: '{{ doc.google_web_font_for_heading or doc.heading_font }}', 'Helvetica Neue', Arial !important;
}{% endif %}
@@ -41,29 +37,27 @@ div.outer {
text-transform: {{ doc.heading_text_style }};
}{% endif %}

{% if doc.page_headings %}h1, h2, h3, h4, h5 {
color: #{{ doc.page_headings }};
}{% endif %}

{% if doc.page_border %}
/* Page Border*/
div.outer {
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
-webkibox-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
{% if doc.page_header_color -%}
.page-header h1, .page-header h2, .page-header h3, .page-header h4, .page-header h5, .page-header {
color: #{{ doc.page_header_color }};
}
{% else %}
{% if doc.background_color.lower() == doc.page_background.lower() %}
.web-footer {
padding-top: 10px;
{%- endif %}
{% if doc.page_header_background -%}
.page-header {
background-color: #{{ doc.page_header_background }};
}
{% endif %}
{% endif %}
{%- endif %}

{% if doc.footer_color -%}
.web-footer, .web-footer a {
font-size: 90%;
color: #{{ doc.background_color | get_hex_shade(100) }};
color: #{{ doc.footer_color }} !important;
}
{% endif -%}
{% if doc.footer_background -%}
.web-footer {
background-color: #{{ doc.footer_background }};
}
{% endif -%}

/* Bootstrap Navbar */
.navbar-default {
@@ -74,11 +68,6 @@ div.outer {
background-color: #{{ doc.top_bar_background}};
background-repeat: repeat-x;
background-image: none;
border-bottom: 1px solid {% if doc.top_bar_background.lower() == doc.page_background.lower() -%}
#{{ doc.page_background | get_hex_shade(15) }};
{%- else -%}
transparent;
{%- endif %}
}

.navbar .navbar-brand,
@@ -185,7 +174,7 @@ div.outer {
}

.breadcrumb {
background-color: #{{ doc.page_background | get_hex_shade(5) }};
background-color: #{{ doc.background_color | get_hex_shade(5) }};
}

.breadcrumb > li {
@@ -195,41 +184,41 @@ div.outer {

.table-striped tbody > tr:nth-child(odd) > td,
.table-striped tbody > tr:nth-child(odd) > th {
background-color: #{{ doc.page_background | get_hex_shade(5) }};
background-color: #{{ doc.background_color | get_hex_shade(5) }};
}

.table-hover tbody tr:hover td,
.table-hover tbody tr:hover th {
background-color: #{{ doc.page_background | get_hex_shade(10) }};
background-color: #{{ doc.background_color | get_hex_shade(10) }};
}

.table-bordered {
border: 1px solid #{{ doc.page_background | get_hex_shade(15) }};
border: 1px solid #{{ doc.background_color | get_hex_shade(15) }};
}

.table th,
.table td {
border-top: 1px solid #{{ doc.page_background | get_hex_shade(15) }};
border-top: 1px solid #{{ doc.background_color | get_hex_shade(15) }};
}

.table-bordered th,
.table-bordered td {
border-left: 1px solid #{{ doc.page_background | get_hex_shade(15) }};
border-left: 1px solid #{{ doc.background_color | get_hex_shade(15) }};
}



.hero-unit {
background-color: #{{ doc.page_background | get_hex_shade(15) }};
background-color: #{{ doc.background_color | get_hex_shade(15) }};
}

pre, code {
background-color: #{{ doc.page_background | get_hex_shade(5) }};
background-color: #{{ doc.background_color | get_hex_shade(5) }};
}

hr {
border-top: 1px solid #{{ doc.page_background | get_hex_shade(15) }};
border-bottom: 1px solid #{{ doc.page_background | get_hex_shade(5) }};
border-top: 1px solid #{{ doc.background_color | get_hex_shade(15) }};
border-bottom: 1px solid #{{ doc.background_color | get_hex_shade(5) }};
}

{% if doc.add_css -%}


+ 15
- 16
frappe/templates/pages/style_settings.py 查看文件

@@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# MIT License. See license.txt

from __future__ import unicode_literals
import frappe
@@ -11,55 +11,54 @@ def get_context(context):
"""returns web style"""
doc = frappe.get_doc("Style Settings", "Style Settings")
prepare(doc)
return { "doc": doc.as_dict() }

print doc.page_header_color

return { "doc": doc.as_dict() }

def prepare(doc):
from frappe.utils import cint, cstr
# set default colours
default_colours = {
"background_color": "FFFFFF",
"page_background": "FFFFFF",
"top_bar_background": "FFFFFF",
"top_bar_foreground": "444444",
"page_headings": "222222",
"page_text": "000000"
}
for d in default_colours:
if not doc.get(d):
doc.set(d, default_colours[d])
if not doc.font_size:
doc.font_size = "14px"
doc.small_font_size = cstr(cint(doc.font_size[:-2])-2) + 'px'
doc.page_border = cint(doc.page_border)

fonts = []
if doc.google_web_font_for_heading:
fonts.append(doc.google_web_font_for_heading)
if doc.google_web_font_for_text:
fonts.append(doc.google_web_font_for_text)
fonts = list(set(fonts))
if doc.heading_text_as:
doc.heading_text_style = {
"UPPERCASE": "uppercase",
"Title Case":"capitalize",
"lowercase": "lowercase"
}.get(doc.heading_text_as) or ""
doc.at_import = ""
for f in fonts:
doc.at_import += "\n@import url(https://fonts.googleapis.com/css?family=%s:400,700);" % f.replace(" ", "+")
# move @import from add_css field to the top of the css file
if doc.add_css and "@import url" in doc.add_css:
import re
at_imports = list(set(re.findall("@import url\([^\(\)]*\);", doc.add_css)))
doc.at_import += "\n" + "\n".join(at_imports)
for imp in at_imports:
doc.add_css = doc.add_css.replace(imp, "")
doc.add_css = doc.add_css.replace(imp, "")

+ 9
- 8
frappe/utils/dateutils.py 查看文件

@@ -12,21 +12,22 @@ dateformats = {
'yyyy-mm-dd': '%Y-%m-%d',
'mm/dd/yyyy': '%m/%d/%Y',
'mm-dd-yyyy': '%m-%d-%Y',
"mm/dd/yy": "%m/%d/%y",
"mm/dd/yy": "%m/%d/%y",
'dd-mmm-yyyy': '%d-%b-%Y', # numbers app format
'dd/mm/yyyy': '%d/%m/%Y',
'dd.mm.yyyy': '%d.%m.%Y',
'dd-mm-yyyy': '%d-%m-%Y',
"dd/mm/yy": "%d/%m/%y",
}

def user_to_str(date, date_format=None):
if not date: return date
if not date_format:
date_format = get_user_date_format()

try:
return datetime.datetime.strptime(date,
return datetime.datetime.strptime(date,
dateformats[date_format]).strftime('%Y-%m-%d')
except ValueError, e:
raise ValueError, "Date %s must be in format %s" % (date, date_format)
@@ -34,11 +35,11 @@ def user_to_str(date, date_format=None):
def parse_date(date):
"""tries to parse given date to system's format i.e. yyyy-mm-dd. returns a string"""
parsed_date = None
# why the sorting? checking should be done in a predictable order
check_formats = [None] + sorted(dateformats.keys(),
reverse=not get_user_date_format().startswith("dd"))
for f in check_formats:
try:
parsed_date = user_to_str(date, f)
@@ -53,17 +54,17 @@ def parse_date(date):
(date, get_user_date_format())

return parsed_date
def get_user_date_format():
if getattr(frappe.local, "user_date_format", None) is None:
frappe.local.user_date_format = frappe.defaults.get_global_default("date_format") or "yyyy-mm-dd"

return frappe.local.user_date_format
def datetime_in_user_format(date_time):
if not date_time:
return ""
if isinstance(date_time, basestring):
date_time = get_datetime(date_time)
from frappe.utils import formatdate
return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M")
return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M")

+ 1
- 0
frappe/website/css/website.css 查看文件

@@ -49,6 +49,7 @@ img {

.web-footer {
padding: 20px 0px;
min-height: 140px;
}

.avatar {


+ 5
- 3
frappe/website/doctype/style_settings/style_settings.js 查看文件

@@ -4,9 +4,11 @@

cur_frm.cscript.onload_post_render = function() {
frappe.require('assets/frappe/js/lib/jscolor/jscolor.js');
$.each(["background_color", "page_background", "page_text", "page_links",
"top_bar_background", "top_bar_foreground", "page_headings"], function(i, v) {
$.each(["background_color", "page_text", "page_links",
"top_bar_background", "top_bar_foreground",
"page_header_background", "page_header_color",
"footer_background", "footer_color"], function(i, v) {
$(cur_frm.fields_dict[v].input).addClass('color');
})
jscolor.bind();
}
}

+ 65
- 21
frappe/website/doctype/style_settings/style_settings.json 查看文件

@@ -8,7 +8,7 @@
{
"fieldname": "enable",
"fieldtype": "Section Break",
"in_list_view": 1,
"in_list_view": 0,
"label": "Enable",
"permlevel": 0
},
@@ -23,8 +23,8 @@
{
"fieldname": "color",
"fieldtype": "Section Break",
"in_list_view": 1,
"label": "Color",
"in_list_view": 0,
"label": "Page Background",
"permlevel": 0
},
{
@@ -45,38 +45,31 @@
"permlevel": 0
},
{
"fieldname": "page_background",
"fieldname": "page_text",
"fieldtype": "Data",
"label": "Page Background",
"permlevel": 0
},
{
"fieldname": "page_border",
"fieldtype": "Check",
"label": "Page Border",
"label": "Page Text",
"permlevel": 0
},
{
"fieldname": "page_headings",
"fieldname": "page_links",
"fieldtype": "Data",
"label": "Page Headings",
"label": "Page Links",
"permlevel": 0
},
{
"fieldname": "page_text",
"fieldtype": "Data",
"label": "Page Text",
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "page_links",
"fieldtype": "Data",
"label": "Page Links",
"fieldname": "html_9",
"fieldtype": "HTML",
"options": "<img class=\"img-responsive\" src=\"/assets/frappe/images/help/style-settings-help.png\">",
"permlevel": 0
},
{
"fieldname": "cb0",
"fieldtype": "Column Break",
"fieldtype": "Section Break",
"label": "Top Bar",
"permlevel": 0,
"print_width": "50%",
@@ -88,6 +81,11 @@
"label": "Top Bar Background",
"permlevel": 0
},
{
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "000 is black, fff is white",
"fieldname": "top_bar_foreground",
@@ -95,6 +93,52 @@
"label": "Top Bar Text",
"permlevel": 0
},
{
"fieldname": "page_header",
"fieldtype": "Section Break",
"label": "Page Header",
"permlevel": 0
},
{
"fieldname": "page_header_background",
"fieldtype": "Data",
"label": "Page Header Background",
"permlevel": 0
},
{
"fieldname": "column_break_16",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "page_header_color",
"fieldtype": "Data",
"label": "Page Header Text",
"permlevel": 0
},
{
"fieldname": "footer",
"fieldtype": "Section Break",
"label": "Footer",
"permlevel": 0
},
{
"fieldname": "footer_background",
"fieldtype": "Data",
"label": "Footer Background",
"permlevel": 0
},
{
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "footer_color",
"fieldtype": "Data",
"label": "Footer Text",
"permlevel": 0
},
{
"fieldname": "fonts",
"fieldtype": "Section Break",
@@ -174,7 +218,7 @@
"idx": 1,
"issingle": 1,
"max_attachments": 1,
"modified": "2014-05-03 14:57:55.879426",
"modified": "2014-05-28 01:58:45.392210",
"modified_by": "Administrator",
"module": "Website",
"name": "Style Settings",


+ 3
- 8
frappe/website/doctype/style_settings/style_settings.py 查看文件

@@ -10,22 +10,17 @@ from frappe import _
from frappe.model.document import Document

class StyleSettings(Document):
def validate(self):
"""make custom css"""
self.validate_colors()
def validate_colors(self):
if (self.page_background or self.page_text) and \
self.page_background==self.page_text:
frappe.msgprint(_("Page text and background is same color. Please change."),
raise_exception=1)

def validate_colors(self):
if (self.top_bar_background or self.top_bar_foreground) and \
self.top_bar_background==self.top_bar_foreground:
frappe.msgprint(_("Top Bar text and background is same color. Please change."),
raise_exception=1)
def on_update(self):
"""clear cache"""
from frappe.sessions import clear_cache


+ 27
- 1
frappe/website/doctype/web_page/web_page.py 查看文件

@@ -2,10 +2,36 @@
# MIT License. See license.txt

from __future__ import unicode_literals
import frappe, os, time
import frappe, os, time, re
import requests, requests.exceptions
from frappe.website.website_generator import WebsiteGenerator
from frappe.website.utils import cleanup_page_name
from frappe.utils import cint

class WebPage(WebsiteGenerator):
save_versions = True

def check_broken_links():
cnt = 0
for p in frappe.db.sql("select name, main_section from `tabWeb Page`", as_dict=True):
for link in re.findall('href=["\']([^"\']*)["\']', p.main_section):
if link.startswith("http"):
try:
res = requests.get(link)
except requests.exceptions.SSLError:
res = frappe._dict({"status_code": "SSL Error"})
except requests.exceptions.ConnectionError:
res = frappe._dict({"status_code": "Connection Error"})

if res.status_code!=200:
print "[{0}] {1}: {2}".format(res.status_code, p.name, link)
cnt += 1
else:
link = link[1:] # remove leading /
link = link.split("#")[0]

if not frappe.db.exists("Website Route", link):
print p.name + ":" + link
cnt += 1

print "{0} links broken".format(cnt)

正在加载...
取消
保存