@@ -203,7 +203,7 @@ class Workspace: | |||
cards = cards + get_custom_reports_and_doctypes(self.doc.module) | |||
if len(self.extended_cards): | |||
cards = cards + self.extended_cards | |||
cards = merge_cards_based_on_label(cards + self.extended_cards) | |||
default_country = frappe.db.get_default("country") | |||
def _doctype_contains_a_record(name): | |||
@@ -579,3 +579,16 @@ def update_onboarding_step(name, field, value): | |||
""" | |||
frappe.db.set_value("Onboarding Step", name, field, value) | |||
def merge_cards_based_on_label(cards): | |||
"""Merge cards with common label.""" | |||
cards_dict = {} | |||
for card in cards: | |||
if card.label in cards_dict: | |||
links = loads(cards_dict[card.label].links) + loads(card.links) | |||
cards_dict[card.label].update(dict(links=dumps(links))) | |||
cards_dict[card.label] = cards_dict.pop(card.label) | |||
else: | |||
cards_dict[card.label] = card | |||
return list(cards_dict.values()) |
@@ -301,6 +301,7 @@ frappe.patches.v13_0.rename_is_custom_field_in_dashboard_chart | |||
frappe.patches.v13_0.add_standard_navbar_items | |||
frappe.patches.v13_0.generate_theme_files_in_public_folder | |||
frappe.patches.v13_0.increase_password_length | |||
frappe.patches.v12_0.fix_email_id_formatting | |||
frappe.patches.v13_0.add_toggle_width_in_navbar_settings | |||
frappe.patches.v13_0.rename_notification_fields | |||
frappe.patches.v13_0.remove_duplicate_navbar_items | |||
@@ -0,0 +1,44 @@ | |||
import frappe | |||
def execute(): | |||
fix_communications() | |||
fix_show_as_cc_email_queue() | |||
fix_email_queue_recipients() | |||
def fix_communications(): | |||
for communication in frappe.db.sql('''select name, recipients, cc, bcc from tabCommunication | |||
where creation > '2020-06-01' | |||
and communication_medium='Email' | |||
and communication_type='Communication' | |||
and (cc like '%<%' or bcc like '%<%' or recipients like '%<%') | |||
''', as_dict=1): | |||
communication['recipients'] = format_email_id(communication.recipients) | |||
communication['cc'] = format_email_id(communication.cc) | |||
communication['bcc'] = format_email_id(communication.bcc) | |||
frappe.db.sql('''update `tabCommunication` set recipients=%s,cc=%s,bcc=%s | |||
where name =%s ''', (communication['recipients'], communication['cc'], | |||
communication['bcc'], communication['name'])) | |||
def fix_show_as_cc_email_queue(): | |||
for queue in frappe.get_all("Email Queue", {'creation': ['>', '2020-06-01'], | |||
'status': 'Not Sent', 'show_as_cc': ['like', '%<%']}, | |||
['name', 'show_as_cc']): | |||
frappe.db.set_value('Email Queue', queue['name'], | |||
'show_as_cc', format_email_id(queue['show_as_cc'])) | |||
def fix_email_queue_recipients(): | |||
for recipient in frappe.db.sql('''select recipient, name from | |||
`tabEmail Queue Recipient` where recipient like '%<%' | |||
and status='Not Sent' and creation > '2020-06-01' ''', as_dict=1): | |||
frappe.db.set_value('Email Queue Recipient', recipient['name'], | |||
'recipient', format_email_id(recipient['recipient'])) | |||
def format_email_id(email): | |||
if email and ('<' in email and '>' in email): | |||
return email.replace('>', '>').replace('<', '<') | |||
return email |
@@ -9,4 +9,4 @@ def execute(): | |||
frappe.db.sql(""" | |||
UPDATE tabNewsletter | |||
SET content_type = 'Rich Text' | |||
""") | |||
""") |
@@ -276,32 +276,32 @@ export default class GridRow { | |||
make_column(df, colsize, txt, ci) { | |||
let me = this; | |||
var add_class = ((["Text", "Small Text"].indexOf(df.fieldtype) !== -1) ? | |||
var add_class = ((["Text", "Small Text"].indexOf(df.fieldtype)!==-1) ? | |||
" grid-overflow-no-ellipsis" : ""); | |||
add_class += (["Int", "Currency", "Float", "Percent"].indexOf(df.fieldtype) !== -1) ? | |||
" text-right" : ""; | |||
add_class += (["Check"].indexOf(df.fieldtype) !== -1) ? | |||
" text-center" : ""; | |||
add_class += (["Int", "Currency", "Float", "Percent"].indexOf(df.fieldtype)!==-1) ? | |||
" text-right": ""; | |||
add_class += (["Check"].indexOf(df.fieldtype)!==-1) ? | |||
" text-center": ""; | |||
var $col = $('<div class="col grid-static-col col-xs-' + colsize + ' ' + add_class + '"></div>') | |||
var $col = $('<div class="col grid-static-col col-xs-'+colsize+' '+add_class+'"></div>') | |||
.attr("data-fieldname", df.fieldname) | |||
.attr("data-fieldtype", df.fieldtype) | |||
.data("df", df) | |||
.appendTo(this.row) | |||
.on('click', function () { | |||
if (frappe.ui.form.editable_row === me) { | |||
.on('click', function() { | |||
if(frappe.ui.form.editable_row===me) { | |||
return; | |||
} | |||
var out = me.toggle_editable_row(); | |||
var col = this; | |||
setTimeout(function () { | |||
setTimeout(function() { | |||
$(col).find('input[type="Text"]:first').focus(); | |||
}, 500); | |||
return out; | |||
}); | |||
$col.field_area = $('<div class="field-area"></div>').appendTo($col).toggle(false); | |||
$col.static_area = $('<div class="static-area ellipsis"></div>').appendTo($col).html(frappe.utils.escape_html(txt)); | |||
$col.static_area = $('<div class="static-area ellipsis"></div>').appendTo($col).html(txt); | |||
$col.df = df; | |||
$col.column_index = ci; | |||
@@ -577,39 +577,39 @@ export default class GridRow { | |||
var df = this.grid.get_docfield(fieldname) || undefined; | |||
// format values if no frm | |||
if (!df) { | |||
if(!df) { | |||
df = this.grid.visible_columns.find((col) => { | |||
return col[0].fieldname === fieldname; | |||
}); | |||
if (df && this.doc) { | |||
if(df && this.doc) { | |||
var txt = frappe.format(this.doc[fieldname], df[0], | |||
null, this.doc); | |||
} | |||
} | |||
if (txt === undefined && this.frm) { | |||
if(txt===undefined && this.frm) { | |||
var txt = frappe.format(this.doc[fieldname], df, | |||
null, this.frm.doc); | |||
} | |||
// reset static value | |||
var column = this.columns[fieldname]; | |||
if (column) { | |||
column.static_area.html(frappe.utils.escape_html(txt) || ""); | |||
if (df && df.reqd) { | |||
column.toggleClass('error', !!(txt === null || txt === '')); | |||
if(column) { | |||
column.static_area.html(txt || ""); | |||
if(df && df.reqd) { | |||
column.toggleClass('error', !!(txt===null || txt==='')); | |||
} | |||
} | |||
// reset field value | |||
var field = this.on_grid_fields_dict[fieldname]; | |||
if (field) { | |||
if(field) { | |||
field.docname = this.doc.name; | |||
field.refresh(); | |||
} | |||
// in form | |||
if (this.grid_form) { | |||
if(this.grid_form) { | |||
this.grid_form.refresh_field(fieldname); | |||
} | |||
} | |||
@@ -3304,7 +3304,7 @@ Daily Long,روزانه طولانی, | |||
Data Import Beta,واردات داده بتا, | |||
Default Role on Creation,نقش پیش فرض در آفرینش, | |||
Default Theme,موضوع پیش فرض, | |||
Default {0},پیش فرض {0, | |||
Default {0},پیش فرض {0}, | |||
Delete All,حذف همه, | |||
"Determines the order of the slide in the wizard. If the slide is not to be displayed, priority should be set to 0.",ترتیب اسلاید در جادوگر را تعیین می کند. اگر اسلاید نمایش داده نمی شود ، اولویت باید بر روی 0 تنظیم شود., | |||
Do you want to cancel all linked documents?,آیا می خواهید کلیه اسناد مرتبط را لغو کنید؟, | |||
@@ -29,7 +29,7 @@ class BackupGenerator: | |||
""" | |||
def __init__(self, db_name, user, password, backup_path_db=None, backup_path_files=None, | |||
backup_path_private_files=None, db_host="localhost", db_port=None, verbose=False, | |||
db_type='mariadb'): | |||
db_type='mariadb', backup_path_conf=None): | |||
global _verbose | |||
self.db_host = db_host | |||
self.db_port = db_port | |||
@@ -37,8 +37,9 @@ class BackupGenerator: | |||
self.db_type = db_type | |||
self.user = user | |||
self.password = password | |||
self.backup_path_files = backup_path_files | |||
self.backup_path_conf = backup_path_conf | |||
self.backup_path_db = backup_path_db | |||
self.backup_path_files = backup_path_files | |||
self.backup_path_private_files = backup_path_private_files | |||
if not self.db_type: | |||
@@ -99,11 +100,14 @@ class BackupGenerator: | |||
def set_backup_file_name(self): | |||
#Generate a random name using today's date and a 8 digit random number | |||
for_conf = self.todays_date + "-" + self.site_slug + "-site_config_backup.json" | |||
for_db = self.todays_date + "-" + self.site_slug + "-database.sql.gz" | |||
for_public_files = self.todays_date + "-" + self.site_slug + "-files.tar" | |||
for_private_files = self.todays_date + "-" + self.site_slug + "-private-files.tar" | |||
backup_path = get_backup_path() | |||
if not self.backup_path_conf: | |||
self.backup_path_conf = os.path.join(backup_path, for_conf) | |||
if not self.backup_path_db: | |||
self.backup_path_db = os.path.join(backup_path, for_db) | |||
if not self.backup_path_files: | |||
@@ -166,19 +170,11 @@ class BackupGenerator: | |||
print('Backed up files', os.path.abspath(backup_path)) | |||
def copy_site_config(self): | |||
site_config_backup_path = os.path.join( | |||
get_backup_path(), | |||
"{time_stamp}-{site_slug}-site_config_backup.json".format( | |||
time_stamp=self.todays_date, | |||
site_slug=self.site_slug)) | |||
site_config_backup_path = self.backup_path_conf | |||
site_config_path = os.path.join(frappe.get_site_path(), "site_config.json") | |||
site_config = {} | |||
if os.path.exists(site_config_path): | |||
site_config.update(frappe.get_file_json(site_config_path)) | |||
with open(site_config_backup_path, "w") as f: | |||
f.write(json.dumps(site_config, indent=2)) | |||
f.flush() | |||
self.site_config_backup_path = site_config_backup_path | |||
with open(site_config_backup_path, "w") as n, open(site_config_path) as c: | |||
n.write(c.read()) | |||
def take_dump(self): | |||
import frappe.utils | |||
@@ -50,7 +50,7 @@ def get_safe_globals(): | |||
dict=dict, | |||
_dict=frappe._dict, | |||
frappe=frappe._dict( | |||
flags=frappe.flags, | |||
flags=frappe._dict(), | |||
format=frappe.format_value, | |||
format_value=frappe.format_value, | |||
date_format=date_format, | |||
@@ -21,6 +21,7 @@ | |||
"dependencies": { | |||
"ace-builds": "^1.4.8", | |||
"air-datepicker": "http://github.com/frappe/air-datepicker", | |||
"autoprefixer": "^9.8.6", | |||
"awesomplete": "^1.1.5", | |||
"bootstrap": "^4.4.1", | |||
"cookie": "^0.4.0", | |||
@@ -117,6 +117,7 @@ function get_rollup_options_for_css(output_file, input_files) { | |||
// less -> css | |||
postcss({ | |||
plugins: [ | |||
starts_with_css ? require('autoprefixer')() : null, | |||
starts_with_css && production ? require('cssnano')({ preset: 'default' }) : null | |||
].filter(Boolean), | |||
extract: output_path, | |||
@@ -836,6 +836,19 @@ atob@^2.1.1: | |||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" | |||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== | |||
autoprefixer@^9.8.6: | |||
version "9.8.6" | |||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" | |||
integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== | |||
dependencies: | |||
browserslist "^4.12.0" | |||
caniuse-lite "^1.0.30001109" | |||
colorette "^1.2.1" | |||
normalize-range "^0.1.2" | |||
num2fraction "^1.2.2" | |||
postcss "^7.0.32" | |||
postcss-value-parser "^4.1.0" | |||
available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: | |||
version "1.0.2" | |||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" | |||
@@ -1048,6 +1061,16 @@ browserslist@^4.0.0: | |||
electron-to-chromium "^1.3.113" | |||
node-releases "^1.1.8" | |||
browserslist@^4.12.0: | |||
version "4.14.0" | |||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" | |||
integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== | |||
dependencies: | |||
caniuse-lite "^1.0.30001111" | |||
electron-to-chromium "^1.3.523" | |||
escalade "^3.0.2" | |||
node-releases "^1.1.60" | |||
buble@^0.19.6: | |||
version "0.19.6" | |||
resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.6.tgz#915909b6bd5b11ee03b1c885ec914a8b974d34d3" | |||
@@ -1203,6 +1226,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939: | |||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001116.tgz" | |||
integrity sha512-f2lcYnmAI5Mst9+g0nkMIznFGsArRmZ0qU+dnq8l91hymdc2J3SFbiPhOJEeDqC1vtE8nc1qNQyklzB8veJefQ== | |||
caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: | |||
version "1.0.30001118" | |||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001118.tgz#116a9a670e5264aec895207f5e918129174c6f62" | |||
integrity sha512-RNKPLojZo74a0cP7jFMidQI7nvLER40HgNfgKQEJ2PFm225L0ectUungNQoK3Xk3StQcFbpBPNEvoWD59436Hg== | |||
caseless@~0.12.0: | |||
version "0.12.0" | |||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" | |||
@@ -1427,6 +1455,11 @@ color@^3.0.0: | |||
color-convert "^1.9.1" | |||
color-string "^1.5.2" | |||
colorette@^1.2.1: | |||
version "1.2.1" | |||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" | |||
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== | |||
combined-stream@^1.0.6, combined-stream@~1.0.6: | |||
version "1.0.8" | |||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" | |||
@@ -2134,6 +2167,11 @@ electron-to-chromium@^1.3.113: | |||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" | |||
integrity sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g== | |||
electron-to-chromium@^1.3.523: | |||
version "1.3.551" | |||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.551.tgz#a94d243a4ca90705189bd4a5eca4e0f56b745a4f" | |||
integrity sha512-11qcm2xvf2kqeFO5EIejaBx5cKXsW1quAyv3VctCMYwofnyVZLs97y6LCekss3/ghQpr7PYkSO3uId5FmxZsdw== | |||
elegant-spinner@^1.0.1: | |||
version "1.0.1" | |||
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" | |||
@@ -2309,6 +2347,11 @@ es6-promisify@^5.0.0: | |||
dependencies: | |||
es6-promise "^4.0.3" | |||
escalade@^3.0.2: | |||
version "3.0.2" | |||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" | |||
integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== | |||
escape-goat@^2.0.0: | |||
version "2.1.1" | |||
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" | |||
@@ -4816,6 +4859,11 @@ node-gyp@^3.8.0: | |||
tar "^2.0.0" | |||
which "1" | |||
node-releases@^1.1.60: | |||
version "1.1.60" | |||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" | |||
integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== | |||
node-releases@^1.1.8: | |||
version "1.1.9" | |||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.9.tgz#70d0985ec4bf7de9f08fc481f5dae111889ca482" | |||
@@ -4878,6 +4926,11 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: | |||
semver "2 || 3 || 4 || 5" | |||
validate-npm-package-license "^3.0.1" | |||
normalize-range@^0.1.2: | |||
version "0.1.2" | |||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" | |||
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= | |||
normalize-url@^3.0.0: | |||
version "3.3.0" | |||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" | |||
@@ -4912,6 +4965,11 @@ nth-check@^1.0.2: | |||
dependencies: | |||
boolbase "~1.0.0" | |||
num2fraction@^1.2.2: | |||
version "1.2.2" | |||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" | |||
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= | |||
number-is-nan@^1.0.0: | |||
version "1.0.1" | |||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" | |||
@@ -5731,6 +5789,11 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.1: | |||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" | |||
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== | |||
postcss-value-parser@^4.1.0: | |||
version "4.1.0" | |||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" | |||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== | |||
postcss@6.0.1: | |||
version "6.0.1" | |||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" | |||
@@ -5768,6 +5831,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.5: | |||
source-map "^0.6.1" | |||
supports-color "^6.1.0" | |||
postcss@^7.0.32: | |||
version "7.0.32" | |||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" | |||
integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== | |||
dependencies: | |||
chalk "^2.4.2" | |||
source-map "^0.6.1" | |||
supports-color "^6.1.0" | |||
prelude-ls@~1.1.2: | |||
version "1.1.2" | |||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" | |||