Merge branch 'develop' into form-builder-fixes
This commit is contained in:
commit
ce287f23d1
8 changed files with 93 additions and 24 deletions
|
|
@ -109,7 +109,8 @@ def new_site(
|
|||
"--with-public-files", help="Restores the public files of the site, given path to its tar file"
|
||||
)
|
||||
@click.option(
|
||||
"--with-private-files", help="Restores the private files of the site, given path to its tar file"
|
||||
"--with-private-files",
|
||||
help="Restores the private files of the site, given path to its tar file",
|
||||
)
|
||||
@click.option(
|
||||
"--force",
|
||||
|
|
@ -191,7 +192,8 @@ def _restore(
|
|||
fg="red",
|
||||
)
|
||||
click.secho(
|
||||
"Use `bench partial-restore` to restore a partial backup to an existing site.", fg="yellow"
|
||||
"Use `bench partial-restore` to restore a partial backup to an existing site.",
|
||||
fg="yellow",
|
||||
)
|
||||
_backup.decryption_rollback()
|
||||
sys.exit(1)
|
||||
|
|
@ -222,7 +224,8 @@ def _restore(
|
|||
fg="red",
|
||||
)
|
||||
click.secho(
|
||||
"Use `bench partial-restore` to restore a partial backup to an existing site.", fg="yellow"
|
||||
"Use `bench partial-restore` to restore a partial backup to an existing site.",
|
||||
fg="yellow",
|
||||
)
|
||||
_backup.decryption_rollback()
|
||||
sys.exit(1)
|
||||
|
|
@ -324,7 +327,8 @@ def partial_restore(context, sql_file_path, verbose, encryption_key=None):
|
|||
# Check for full backup file
|
||||
if "Partial Backup" not in header:
|
||||
click.secho(
|
||||
"Full backup file detected.Use `bench restore` to restore a Frappe Site.", fg="red"
|
||||
"Full backup file detected.Use `bench restore` to restore a Frappe Site.",
|
||||
fg="red",
|
||||
)
|
||||
_backup.decryption_rollback()
|
||||
sys.exit(1)
|
||||
|
|
@ -355,7 +359,8 @@ def partial_restore(context, sql_file_path, verbose, encryption_key=None):
|
|||
# Check for Full backup file.
|
||||
if "Partial Backup" not in header:
|
||||
click.secho(
|
||||
"Full Backup file detected.Use `bench restore` to restore a Frappe Site.", fg="red"
|
||||
"Full Backup file detected.Use `bench restore` to restore a Frappe Site.",
|
||||
fg="red",
|
||||
)
|
||||
_backup.decryption_rollback()
|
||||
sys.exit(1)
|
||||
|
|
@ -391,7 +396,12 @@ def reinstall(
|
|||
|
||||
|
||||
def _reinstall(
|
||||
site, admin_password=None, db_root_username=None, db_root_password=None, yes=False, verbose=False
|
||||
site,
|
||||
admin_password=None,
|
||||
db_root_username=None,
|
||||
db_root_password=None,
|
||||
yes=False,
|
||||
verbose=False,
|
||||
):
|
||||
from frappe.installer import _new_site
|
||||
from frappe.utils.synchronization import filelock
|
||||
|
|
@ -719,7 +729,10 @@ def use(site, sites_path="."):
|
|||
@click.option("--backup-path-private-files", default=None, help="Set path for saving private file")
|
||||
@click.option("--backup-path-conf", default=None, help="Set path for saving config file")
|
||||
@click.option(
|
||||
"--ignore-backup-conf", default=False, is_flag=True, help="Ignore excludes/includes set in config"
|
||||
"--ignore-backup-conf",
|
||||
default=False,
|
||||
is_flag=True,
|
||||
help="Ignore excludes/includes set in config",
|
||||
)
|
||||
@click.option("--verbose", default=False, is_flag=True, help="Add verbosity")
|
||||
@click.option("--compress", default=False, is_flag=True, help="Compress private and public files")
|
||||
|
|
@ -774,7 +787,8 @@ def backup(
|
|||
continue
|
||||
if frappe.get_system_settings("encrypt_backup") and frappe.get_site_config().encryption_key:
|
||||
click.secho(
|
||||
"Backup encryption is turned on. Please note the backup encryption key.", fg="yellow"
|
||||
"Backup encryption is turned on. Please note the backup encryption key.",
|
||||
fg="yellow",
|
||||
)
|
||||
|
||||
odb.print_summary()
|
||||
|
|
@ -1120,14 +1134,31 @@ def stop_recording(context):
|
|||
@click.option(
|
||||
"--bind-tls", is_flag=True, default=False, help="Returns a reference to the https tunnel."
|
||||
)
|
||||
@click.option(
|
||||
"--use-default-authtoken",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Use the auth token present in ngrok's config.",
|
||||
)
|
||||
@pass_context
|
||||
def start_ngrok(context, bind_tls):
|
||||
def start_ngrok(context, bind_tls, use_default_authtoken):
|
||||
"""Start a ngrok tunnel to your local development server."""
|
||||
from pyngrok import ngrok
|
||||
|
||||
site = get_site(context)
|
||||
frappe.init(site=site)
|
||||
|
||||
ngrok_authtoken = frappe.conf.ngrok_authtoken
|
||||
if not use_default_authtoken:
|
||||
if not ngrok_authtoken:
|
||||
click.echo(
|
||||
f"\n{click.style('ngrok_authtoken', fg='yellow')} not found in site config.\n"
|
||||
"Please register for a free ngrok account at: https://dashboard.ngrok.com/signup and place the obtained authtoken in the site config.",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
ngrok.set_auth_token(ngrok_authtoken)
|
||||
|
||||
port = frappe.conf.http_port or frappe.conf.webserver_port
|
||||
tunnel = ngrok.connect(addr=str(port), host_header=site, bind_tls=bind_tls)
|
||||
print(f"Public URL: {tunnel.public_url}")
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ def unzip_file(name: str):
|
|||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_attached_images(doctype: str, names: list[str]) -> frappe._dict:
|
||||
def get_attached_images(doctype: str, names: list[str] | str) -> frappe._dict:
|
||||
"""get list of image urls attached in form
|
||||
returns {name: ['image.jpg', 'image.png']}"""
|
||||
|
||||
|
|
|
|||
|
|
@ -195,10 +195,12 @@ class DocType(Document):
|
|||
|
||||
def set_default_in_list_view(self):
|
||||
"""Set default in-list-view for first 4 mandatory fields"""
|
||||
not_allowed_in_list_view = get_fields_not_allowed_in_list_view(self.meta)
|
||||
|
||||
if not [d.fieldname for d in self.fields if d.in_list_view]:
|
||||
cnt = 0
|
||||
for d in self.fields:
|
||||
if d.reqd and not d.hidden and not d.fieldtype in table_fields:
|
||||
if d.reqd and not d.hidden and not d.fieldtype in not_allowed_in_list_view:
|
||||
d.in_list_view = 1
|
||||
cnt += 1
|
||||
if cnt == 4:
|
||||
|
|
@ -1446,10 +1448,7 @@ def validate_fields(meta):
|
|||
fields = meta.get("fields")
|
||||
fieldname_list = [d.fieldname for d in fields]
|
||||
|
||||
not_allowed_in_list_view = list(copy.copy(no_value_fields))
|
||||
not_allowed_in_list_view.append("Attach Image")
|
||||
if meta.istable:
|
||||
not_allowed_in_list_view.remove("Button")
|
||||
not_allowed_in_list_view = get_fields_not_allowed_in_list_view(meta)
|
||||
|
||||
for d in fields:
|
||||
if not d.permlevel:
|
||||
|
|
@ -1490,6 +1489,14 @@ def validate_fields(meta):
|
|||
check_image_field(meta)
|
||||
|
||||
|
||||
def get_fields_not_allowed_in_list_view(meta) -> list[str]:
|
||||
not_allowed_in_list_view = list(copy.copy(no_value_fields))
|
||||
not_allowed_in_list_view.append("Attach Image")
|
||||
if meta.istable:
|
||||
not_allowed_in_list_view.remove("Button")
|
||||
return not_allowed_in_list_view
|
||||
|
||||
|
||||
def validate_permissions_for_doctype(doctype, for_remove=False, alert=False):
|
||||
"""Validates if permissions are set correctly."""
|
||||
doctype = frappe.get_doc("DocType", doctype)
|
||||
|
|
|
|||
|
|
@ -722,6 +722,28 @@ class TestDocType(FrappeTestCase):
|
|||
self.assertEqual(frappe.get_meta(doctype).get_field(field).default, "DELETETHIS")
|
||||
frappe.delete_doc("DocType", doctype)
|
||||
|
||||
def test_not_in_list_view_for_not_allowed_mandatory_field(self):
|
||||
doctype = new_doctype(
|
||||
fields=[
|
||||
{
|
||||
"fieldname": "cover_image",
|
||||
"fieldtype": "Attach Image",
|
||||
"label": "Cover Image",
|
||||
"reqd": 1, # mandatory
|
||||
},
|
||||
{
|
||||
"fieldname": "book_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Book Name",
|
||||
"reqd": 1, # mandatory
|
||||
},
|
||||
],
|
||||
).insert()
|
||||
|
||||
self.assertFalse(doctype.fields[0].in_list_view)
|
||||
self.assertTrue(doctype.fields[1].in_list_view)
|
||||
frappe.delete_doc("DocType", doctype.name)
|
||||
|
||||
|
||||
def new_doctype(
|
||||
name: str | None = None,
|
||||
|
|
@ -759,8 +781,7 @@ def new_doctype(
|
|||
}
|
||||
)
|
||||
|
||||
if fields:
|
||||
for f in fields:
|
||||
doc.append("fields", f)
|
||||
if fields and len(fields) > 0:
|
||||
doc.set("fields", fields)
|
||||
|
||||
return doc
|
||||
|
|
|
|||
|
|
@ -57,18 +57,16 @@
|
|||
],
|
||||
"icon": "fa fa-comment",
|
||||
"links": [],
|
||||
"modified": "2022-01-04 14:12:50.321633",
|
||||
"modified": "2023-01-02 03:56:48.437280",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Email",
|
||||
"name": "Email Template",
|
||||
"naming_rule": "Set by user",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"read": 1,
|
||||
"role": "All",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
"role": "All"
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
|
|
@ -85,5 +83,6 @@
|
|||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import json
|
|||
|
||||
# all country info
|
||||
import os
|
||||
from functools import lru_cache
|
||||
|
||||
import frappe
|
||||
from frappe.utils.momentjs import get_all_timezones
|
||||
|
|
@ -27,8 +28,13 @@ def get_all():
|
|||
return all_data
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def get_country_timezone_info():
|
||||
return _get_country_timezone_info()
|
||||
|
||||
|
||||
@lru_cache(maxsize=2)
|
||||
def _get_country_timezone_info():
|
||||
return {"country_info": get_all(), "all_timezones": get_all_timezones()}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ class Document(BaseDocument):
|
|||
"*",
|
||||
as_dict=True,
|
||||
order_by="idx asc",
|
||||
for_update=self.flags.for_update,
|
||||
)
|
||||
or []
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
.page_content {
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
|
||||
.tooltip-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.25rem;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue