diff --git a/frappe/__init__.py b/frappe/__init__.py index e6dd2c3778..f19504b216 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -13,7 +13,7 @@ import os, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template -__version__ = "7.0.8" +__version__ = "7.0.9" local = Local() @@ -296,7 +296,7 @@ def throw(msg, exc=ValidationError, title=None): :param msg: Message. :param exc: Exception class. Default `frappe.ValidationError`""" - msgprint(msg, raise_exception=exc, title=title) + msgprint(msg, raise_exception=exc, title=title, indicator='red') def emit_js(js, user=False, **kwargs): from frappe.async import publish_realtime diff --git a/frappe/docs/assets/img/usage_info.png b/frappe/docs/assets/img/usage_info.png new file mode 100644 index 0000000000..364d9cbc78 Binary files /dev/null and b/frappe/docs/assets/img/usage_info.png differ diff --git a/frappe/docs/user/en/bench/guides/index.txt b/frappe/docs/user/en/bench/guides/index.txt index daceae6369..4f99377c88 100755 --- a/frappe/docs/user/en/bench/guides/index.txt +++ b/frappe/docs/user/en/bench/guides/index.txt @@ -7,4 +7,5 @@ setup-multitenancy setup-production setup-ssl stop-production-and-start-development -updating \ No newline at end of file +updating +setting-limits \ No newline at end of file diff --git a/frappe/docs/user/en/bench/guides/settings-limits.md b/frappe/docs/user/en/bench/guides/settings-limits.md new file mode 100644 index 0000000000..8d2a9e4b1d --- /dev/null +++ b/frappe/docs/user/en/bench/guides/settings-limits.md @@ -0,0 +1,39 @@ +# Setting Limits for your Site + +Frappe v7 has added support for setting limits and restrictions for your site. +These restrictions are set in the `site_config.json` file inside the site's folder. + + { + "db_name": "xxxxxxxxxx", + "db_password": "xxxxxxxxxxxx", + "limits": { + "emails": 1500, + "space": 0.157, + "expiry": "2016-07-25", + "users": 1 + } + } + +You can set a limit by running: + + bench --site [sitename] set-limit [limit] [value] + +You can set multiple limits at the same time, by running + + bench --site [sitename] set-limits --limit [limit] [value] --limit [limit-2] [value-2] + +The valid limits you can set are: + +- **users** - Limit on the number of maximum users for a site +- **emails** - Limit on the number of emails sent per month from the site +- **space** - Limit on the maximum space the site can use (GB) +- **email_group** - Limit on the maximum number of members allowed in an Email Group +- **expiry** - Expiry date for the site (YYYY-MM-DD within quotes) + +Example: + + bench --site site1.local set-limit users 5 + +You can check your usage by opening the "Usage Info" page from the toolbar / AwesomeBar. A limit will only show up on the page if it has been set. + +Doctype Saved diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 382e03fcc8..3321153181 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -511,8 +511,8 @@ class BaseDocument(object): else: reference = "{0} {1}".format(_(self.doctype), self.name) - frappe.throw(_("{0}: '{1}' will get truncated, as max characters allowed is {2}")\ - .format(reference, _(df.label), max_length), frappe.CharacterLengthExceededError) + frappe.throw(_("{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}")\ + .format(reference, _(df.label), max_length, value), frappe.CharacterLengthExceededError, title=_('Value too big')) def _validate_update_after_submit(self): # get the full doc with children diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css index 0902c35ec4..df6a0aa0b7 100644 --- a/frappe/public/css/desk.css +++ b/frappe/public/css/desk.css @@ -405,7 +405,8 @@ fieldset[disabled] .form-control { .ui-menu .ui-menu-item { font-size: 12px; } -.ui-menu .ui-menu-item a { +.ui-menu .ui-menu-item a, +.ui-menu .ui-menu-item div { padding: 9px 11.8px !important; text-decoration: none; } diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css index 6b7d1989eb..1adde0186d 100644 --- a/frappe/public/css/form.css +++ b/frappe/public/css/form.css @@ -92,6 +92,12 @@ .form-heatmap .heatmap-message { margin-top: 10px; } +@media (max-width: 991px) { + .form-heatmap { + overflow: hidden; + overflow-x: scroll; + } +} .inline-graph .inline-graph-half { width: 48%; display: inline-block; diff --git a/frappe/public/css/page.css b/frappe/public/css/page.css index 04fabafdd1..c0557620ca 100644 --- a/frappe/public/css/page.css +++ b/frappe/public/css/page.css @@ -132,7 +132,7 @@ select.input-sm { } @media (max-width: 767px) { .page-actions { - width: 105px; + max-width: 150px; float: right; } .page-title { diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index b2717b1326..64bf17525e 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -221,7 +221,7 @@ textarea.form-control { .ui-menu .ui-menu-item { font-size: @text-medium; - a { + a, div { padding: 9px 11.8px !important; text-decoration: none; } diff --git a/frappe/public/less/form.less b/frappe/public/less/form.less index c5f4656360..43aeea7362 100644 --- a/frappe/public/less/form.less +++ b/frappe/public/less/form.less @@ -125,6 +125,11 @@ .heatmap-message { margin-top: 10px; } + + @media (max-width: @screen-sm) { + overflow: hidden; + overflow-x: scroll; + } } .inline-graph { diff --git a/frappe/public/less/page.less b/frappe/public/less/page.less index eaa3a00c15..4befeb99a2 100644 --- a/frappe/public/less/page.less +++ b/frappe/public/less/page.less @@ -166,7 +166,7 @@ select.input-sm { @media(max-width: @screen-xs) { .page-actions { - width: 105px; + max-width: 150px; float: right; } diff --git a/frappe/website/website_generator.py b/frappe/website/website_generator.py index 51129adada..b81acc8549 100644 --- a/frappe/website/website_generator.py +++ b/frappe/website/website_generator.py @@ -35,7 +35,7 @@ class WebsiteGenerator(Document): self.route = self.make_route() if self.route: - self.route = self.route.strip('/.')[:140] + self.route = self.route.strip('/.')[:139] def make_route(self): return self.scrub(self.get(self.website.page_title_field or "name")) @@ -49,7 +49,7 @@ class WebsiteGenerator(Document): clear_cache(self.route) def scrub(self, text): - return quoted(cleanup_page_name(text).replace('_', '-')) + return cleanup_page_name(text).replace('_', '-') def get_parents(self, context): '''Return breadcrumbs'''