diff --git a/.eslintrc b/.eslintrc
index e79571f556..eef33ec8a0 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -5,7 +5,7 @@
"es6": true
},
"parserOptions": {
- "ecmaVersion": 8,
+ "ecmaVersion": 9,
"sourceType": "module"
},
"extends": "eslint:recommended",
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
deleted file mode 100644
index 26801ebbe8..0000000000
--- a/.github/workflows/backport.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Backport
-on:
- pull_request:
- types:
- - closed
- - labeled
-
-jobs:
- backport:
- runs-on: ubuntu-18.04
- name: Backport
- steps:
- - name: Backport
- uses: tibdex/backport@v1
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/frappe/automation/desk_page/tools/tools.json b/frappe/automation/desk_page/tools/tools.json
index 3cfaa0bd97..235498724d 100644
--- a/frappe/automation/desk_page/tools/tools.json
+++ b/frappe/automation/desk_page/tools/tools.json
@@ -1,22 +1,24 @@
{
"cards": [
{
- "icon": "octicon octicon-briefcase",
- "links": "[\n {\n \"description\": \"Documents assigned to you and by you.\",\n \"label\": \"To Do\",\n \"name\": \"ToDo\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Event and other calendars.\",\n \"label\": \"Calendar\",\n \"link\": \"List/Event/Calendar\",\n \"name\": \"Event\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Private and public Notes.\",\n \"label\": \"Note\",\n \"name\": \"Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Files\",\n \"name\": \"File\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Activity log of all users.\",\n \"label\": \"Activity\",\n \"name\": \"activity\",\n \"type\": \"page\"\n }\n]",
- "title": "Tools"
+ "hidden": 0,
+ "label": "Tools",
+ "links": "[\n {\n \"description\": \"Documents assigned to you and by you.\",\n \"label\": \"To Do\",\n \"name\": \"ToDo\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Event and other calendars.\",\n \"label\": \"Calendar\",\n \"link\": \"List/Event/Calendar\",\n \"name\": \"Event\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Private and public Notes.\",\n \"label\": \"Note\",\n \"name\": \"Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Files\",\n \"name\": \"File\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Activity log of all users.\",\n \"label\": \"Activity\",\n \"name\": \"activity\",\n \"type\": \"page\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Newsletters to contacts, leads.\",\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Email Group List\",\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Email"
+ "hidden": 0,
+ "label": "Email",
+ "links": "[\n {\n \"description\": \"Newsletters to contacts, leads.\",\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Email Group List\",\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"type\": \"doctype\",\n \"name\": \"Assignment Rule\",\n \"description\": \"Set up rules for user assignments.\",\n \"label\": \"Assignment Rule\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Milestone\",\n \"description\": \"Tracks milestones on the lifecycle of a document if it undergoes multiple stages.\",\n \"label\": \"Milestone\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Auto Repeat\",\n \"description\": \"Automatically generates recurring documents.\",\n \"label\": \"Auto Repeat\"\n }\n]",
- "title": "Automation"
+ "hidden": 0,
+ "label": "Automation",
+ "links": "[\n {\n \"type\": \"doctype\",\n \"name\": \"Assignment Rule\",\n \"description\": \"Set up rules for user assignments.\",\n \"label\": \"Assignment Rule\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Milestone\",\n \"description\": \"Tracks milestones on the lifecycle of a document if it undergoes multiple stages.\",\n \"label\": \"Milestone\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Auto Repeat\",\n \"description\": \"Automatically generates recurring documents.\",\n \"label\": \"Auto Repeat\"\n }\n]"
},
{
- "links": "[\n {\n \"type\": \"doctype\",\n \"name\": \"Event Producer\",\n \"description\": \"The site you want to subscribe to for consuming events.\",\n \"label\": \"Event Producer\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Consumer\",\n \"description\": \"The site which is consuming your events.\",\n \"label\": \"Event Consumer\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Update Log\",\n \"description\": \"Maintains a Log of all inserts, updates and deletions on Event Producer site for documents that have consumers.\",\n \"label\": \"Event Update Log\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Sync Log\",\n \"description\": \"Maintains a log of every event consumed along with the status of the sync and a Resync button in case sync fails.\",\n \"label\": \"Event Sync Log\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Document Type Mapping\",\n \"description\": \"The mapping configuration between two doctypes.\",\n \"label\": \"Document Type Mapping\"\n }\n]",
- "title": "Event Streaming"
+ "hidden": 0,
+ "label": "Event Streaming",
+ "links": "[\n {\n \"type\": \"doctype\",\n \"name\": \"Event Producer\",\n \"description\": \"The site you want to subscribe to for consuming events.\",\n \"label\": \"Event Producer\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Consumer\",\n \"description\": \"The site which is consuming your events.\",\n \"label\": \"Event Consumer\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Update Log\",\n \"description\": \"Maintains a Log of all inserts, updates and deletions on Event Producer site for documents that have consumers.\",\n \"label\": \"Event Update Log\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Event Sync Log\",\n \"description\": \"Maintains a log of every event consumed along with the status of the sync and a Resync button in case sync fails.\",\n \"label\": \"Event Sync Log\"\n },\n {\n \"type\": \"doctype\",\n \"name\": \"Document Type Mapping\",\n \"description\": \"The mapping configuration between two doctypes.\",\n \"label\": \"Document Type Mapping\"\n }\n]"
}
],
"category": "Administration",
@@ -30,7 +32,7 @@
"idx": 0,
"is_standard": 1,
"label": "Tools",
- "modified": "2020-03-12 16:30:41.841895",
+ "modified": "2020-04-01 11:24:40.804346",
"modified_by": "Administrator",
"module": "Automation",
"name": "Tools",
@@ -39,27 +41,27 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "ToDo",
"link_to": "ToDo",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Note",
"link_to": "Note",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "File",
"link_to": "File",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Assignment Rule",
"link_to": "Assignment Rule",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Auto Repeat",
"link_to": "Auto Repeat",
"type": "DocType"
}
diff --git a/frappe/core/desk_page/settings/settings.json b/frappe/core/desk_page/settings/settings.json
index 41d1765684..6569b2fb20 100644
--- a/frappe/core/desk_page/settings/settings.json
+++ b/frappe/core/desk_page/settings/settings.json
@@ -1,37 +1,37 @@
{
"cards": [
{
- "icon": "fa fa-th",
- "links": "[\n {\n \"description\": \"Import Data from CSV / Excel files.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Import Data\",\n \"name\": \"Data Import\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Export Data in CSV / Excel format.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Export Data\",\n \"name\": \"Data Export\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Update many values at one time.\",\n \"hide_count\": true,\n \"label\": \"Bulk Update\",\n \"name\": \"Bulk Update\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of backups available for download\",\n \"icon\": \"fa fa-download\",\n \"label\": \"Download Backups\",\n \"name\": \"backups\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Restore or permanently delete a document.\",\n \"label\": \"Deleted Documents\",\n \"name\": \"Deleted Document\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Data"
+ "hidden": 0,
+ "label": "Data",
+ "links": "[\n {\n \"description\": \"Import Data from CSV / Excel files.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Import Data\",\n \"name\": \"Data Import\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Export Data in CSV / Excel format.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Export Data\",\n \"name\": \"Data Export\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Update many values at one time.\",\n \"hide_count\": true,\n \"label\": \"Bulk Update\",\n \"name\": \"Bulk Update\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of backups available for download\",\n \"icon\": \"fa fa-download\",\n \"label\": \"Download Backups\",\n \"name\": \"backups\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Restore or permanently delete a document.\",\n \"label\": \"Deleted Documents\",\n \"name\": \"Deleted Document\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-envelope",
- "links": "[\n {\n \"description\": \"Add / Manage Email Accounts.\",\n \"label\": \"Email Account\",\n \"name\": \"Email Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add / Manage Email Domains.\",\n \"label\": \"Email Domain\",\n \"name\": \"Email Domain\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup Notifications based on various criteria.\",\n \"label\": \"Notification\",\n \"name\": \"Notification\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Email Templates for common queries.\",\n \"label\": \"Email Template\",\n \"name\": \"Email Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup Reports to be emailed at regular intervals\",\n \"label\": \"Auto Email Report\",\n \"name\": \"Auto Email Report\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create and manage newsletter\",\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Configure notifications for mentions, assignments, energy points and more.\",\n \"label\": \"Notification Settings\",\n \"name\": \"Notification Settings\",\n \"route\": \"Form/Notification Settings/Administrator\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Email / Notifications"
+ "hidden": 0,
+ "label": "Email / Notifications",
+ "links": "[\n {\n \"description\": \"Add / Manage Email Accounts.\",\n \"label\": \"Email Account\",\n \"name\": \"Email Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add / Manage Email Domains.\",\n \"label\": \"Email Domain\",\n \"name\": \"Email Domain\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup Notifications based on various criteria.\",\n \"label\": \"Notification\",\n \"name\": \"Notification\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Email Templates for common queries.\",\n \"label\": \"Email Template\",\n \"name\": \"Email Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup Reports to be emailed at regular intervals\",\n \"label\": \"Auto Email Report\",\n \"name\": \"Auto Email Report\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create and manage newsletter\",\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Configure notifications for mentions, assignments, energy points and more.\",\n \"label\": \"Notification Settings\",\n \"name\": \"Notification Settings\",\n \"route\": \"Form/Notification Settings/Administrator\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-globe",
- "links": "[\n {\n \"description\": \"Setup of top navigation bar, footer and logo.\",\n \"label\": \"Website Settings\",\n \"name\": \"Website Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of themes for Website.\",\n \"label\": \"Website Theme\",\n \"name\": \"Website Theme\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Javascript to append to the head section of the page.\",\n \"label\": \"Website Script\",\n \"name\": \"Website Script\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for About Us Page.\",\n \"label\": \"About Us Settings\",\n \"name\": \"About Us Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for Contact Us Page.\",\n \"label\": \"Contact Us Settings\",\n \"name\": \"Contact Us Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Website"
+ "hidden": 0,
+ "label": "Website",
+ "links": "[\n {\n \"description\": \"Setup of top navigation bar, footer and logo.\",\n \"label\": \"Website Settings\",\n \"name\": \"Website Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of themes for Website.\",\n \"label\": \"Website Theme\",\n \"name\": \"Website Theme\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Javascript to append to the head section of the page.\",\n \"label\": \"Website Script\",\n \"name\": \"Website Script\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for About Us Page.\",\n \"label\": \"About Us Settings\",\n \"name\": \"About Us Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for Contact Us Page.\",\n \"label\": \"Contact Us Settings\",\n \"name\": \"Contact Us Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-wrench",
- "links": "[\n {\n \"description\": \"Language, Date and Time settings\",\n \"hide_count\": true,\n \"label\": \"System Settings\",\n \"name\": \"System Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Log of error on automated events (scheduler).\",\n \"label\": \"Error Log\",\n \"name\": \"Error Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Log of error during requests.\",\n \"label\": \"Error Snapshot\",\n \"name\": \"Error Snapshot\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Enable / Disable Domains\",\n \"hide_count\": true,\n \"label\": \"Domain Settings\",\n \"name\": \"Domain Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Core"
+ "hidden": 0,
+ "label": "Core",
+ "links": "[\n {\n \"description\": \"Language, Date and Time settings\",\n \"hide_count\": true,\n \"label\": \"System Settings\",\n \"name\": \"System Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Log of error on automated events (scheduler).\",\n \"label\": \"Error Log\",\n \"name\": \"Error Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Log of error during requests.\",\n \"label\": \"Error Snapshot\",\n \"name\": \"Error Snapshot\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Enable / Disable Domains\",\n \"hide_count\": true,\n \"label\": \"Domain Settings\",\n \"name\": \"Domain Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-print",
- "links": "[\n {\n \"description\": \"Drag and Drop tool to build and customize Print Formats.\",\n \"label\": \"Print Format Builder\",\n \"name\": \"print-format-builder\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Set default format, page size, print style etc.\",\n \"label\": \"Print Settings\",\n \"name\": \"Print Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customized HTML Templates for printing transactions.\",\n \"label\": \"Print Format\",\n \"name\": \"Print Format\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Stylesheets for Print Formats\",\n \"label\": \"Print Style\",\n \"name\": \"Print Style\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Printing"
+ "hidden": 0,
+ "label": "Printing",
+ "links": "[\n {\n \"description\": \"Drag and Drop tool to build and customize Print Formats.\",\n \"label\": \"Print Format Builder\",\n \"name\": \"print-format-builder\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Set default format, page size, print style etc.\",\n \"label\": \"Print Settings\",\n \"name\": \"Print Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customized HTML Templates for printing transactions.\",\n \"label\": \"Print Format\",\n \"name\": \"Print Format\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Stylesheets for Print Formats\",\n \"label\": \"Print Style\",\n \"name\": \"Print Style\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-random",
- "links": "[\n {\n \"description\": \"Define workflows for forms.\",\n \"label\": \"Workflow\",\n \"name\": \"Workflow\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"States for workflow (e.g. Draft, Approved, Cancelled).\",\n \"label\": \"Workflow State\",\n \"name\": \"Workflow State\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Actions for workflow (e.g. Approve, Cancel).\",\n \"label\": \"Workflow Action\",\n \"name\": \"Workflow Action\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Workflow"
+ "hidden": 0,
+ "label": "Workflow",
+ "links": "[\n {\n \"description\": \"Define workflows for forms.\",\n \"label\": \"Workflow\",\n \"name\": \"Workflow\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"States for workflow (e.g. Draft, Approved, Cancelled).\",\n \"label\": \"Workflow State\",\n \"name\": \"Workflow State\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Actions for workflow (e.g. Approve, Cancel).\",\n \"label\": \"Workflow Action\",\n \"name\": \"Workflow Action\",\n \"type\": \"doctype\"\n }\n]"
}
],
- "category": "Administration",
+ "category": "Modules",
"charts": [],
"creation": "2020-03-02 15:09:40.527211",
"developer_mode_only": 0,
@@ -42,29 +42,29 @@
"idx": 0,
"is_standard": 1,
"label": "Settings",
- "modified": "2020-03-12 16:30:43.510434",
+ "modified": "2020-04-01 11:24:40.636747",
"modified_by": "Administrator",
"module": "Core",
"name": "Settings",
"owner": "Administrator",
- "pin_to_bottom": 0,
- "pin_to_top": 1,
+ "pin_to_bottom": 1,
+ "pin_to_top": 0,
"shortcuts": [
{
"icon": "octicon octicon-settings",
- "is_query_report": 0,
+ "label": "System Settings",
"link_to": "System Settings",
"type": "DocType"
},
{
"icon": "fa fa-print",
- "is_query_report": 0,
+ "label": "Print Settings",
"link_to": "Print Settings",
"type": "DocType"
},
{
"icon": "fa fa-globe",
- "is_query_report": 0,
+ "label": "Website Settings",
"link_to": "Website Settings",
"type": "DocType"
}
diff --git a/frappe/core/desk_page/users/users.json b/frappe/core/desk_page/users/users.json
index dc9619314e..30455b86e6 100644
--- a/frappe/core/desk_page/users/users.json
+++ b/frappe/core/desk_page/users/users.json
@@ -1,19 +1,19 @@
{
"cards": [
{
- "icon": "fa fa-group",
- "links": "[\n {\n \"description\": \"System and Website Users\",\n \"label\": \"User\",\n \"name\": \"User\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"User Roles\",\n \"label\": \"Role\",\n \"name\": \"Role\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Role Profile\",\n \"label\": \"Role Profile\",\n \"name\": \"Role Profile\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Users"
+ "hidden": 0,
+ "label": "Users",
+ "links": "[\n {\n \"description\": \"System and Website Users\",\n \"label\": \"User\",\n \"name\": \"User\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"User Roles\",\n \"label\": \"Role\",\n \"name\": \"Role\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Role Profile\",\n \"label\": \"Role Profile\",\n \"name\": \"Role Profile\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-group",
- "links": "[\n {\n \"description\": \"Activity Log by \",\n \"label\": \"Activity Log\",\n \"name\": \"Activity Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"View Log of all print, download and export events\",\n \"label\": \"Access Log\",\n \"name\": \"Access Log\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Logs"
+ "hidden": 0,
+ "label": "Logs",
+ "links": "[\n {\n \"description\": \"Activity Log by \",\n \"label\": \"Activity Log\",\n \"name\": \"Activity Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"View Log of all print, download and export events\",\n \"label\": \"Access Log\",\n \"name\": \"Access Log\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-lock",
- "links": "[\n {\n \"description\": \"Set Permissions on Document Types and Roles\",\n \"icon\": \"fa fa-lock\",\n \"label\": \"Role Permissions Manager\",\n \"name\": \"permission-manager\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Restrict user for specific document\",\n \"icon\": \"fa fa-lock\",\n \"label\": \"User Permissions\",\n \"name\": \"User Permission\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Set custom roles for page and report\",\n \"label\": \"Role Permission for Page and Report\",\n \"name\": \"Role Permission for Page and Report\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"User\"\n ],\n \"description\": \"Check which Documents are readable by a User\",\n \"doctype\": \"User\",\n \"icon\": \"fa fa-eye-open\",\n \"is_query_report\": true,\n \"label\": \"Permitted Documents For User\",\n \"name\": \"Permitted Documents For User\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"DocShare\"\n ],\n \"description\": \"Report of all document shares\",\n \"doctype\": \"DocShare\",\n \"icon\": \"fa fa-share\",\n \"label\": \"Document Share Report\",\n \"name\": \"Document Share Report\",\n \"type\": \"report\"\n }\n]",
- "title": "Permissions"
+ "hidden": 0,
+ "label": "Permissions",
+ "links": "[\n {\n \"description\": \"Set Permissions on Document Types and Roles\",\n \"icon\": \"fa fa-lock\",\n \"label\": \"Role Permissions Manager\",\n \"name\": \"permission-manager\",\n \"type\": \"page\"\n },\n {\n \"description\": \"Restrict user for specific document\",\n \"icon\": \"fa fa-lock\",\n \"label\": \"User Permissions\",\n \"name\": \"User Permission\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Set custom roles for page and report\",\n \"label\": \"Role Permission for Page and Report\",\n \"name\": \"Role Permission for Page and Report\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"User\"\n ],\n \"description\": \"Check which Documents are readable by a User\",\n \"doctype\": \"User\",\n \"icon\": \"fa fa-eye-open\",\n \"is_query_report\": true,\n \"label\": \"Permitted Documents For User\",\n \"name\": \"Permitted Documents For User\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"DocShare\"\n ],\n \"description\": \"Report of all document shares\",\n \"doctype\": \"DocShare\",\n \"icon\": \"fa fa-share\",\n \"label\": \"Document Share Report\",\n \"name\": \"Document Share Report\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Administration",
@@ -27,7 +27,7 @@
"idx": 0,
"is_standard": 1,
"label": "Users",
- "modified": "2020-03-12 16:30:42.483376",
+ "modified": "2020-04-01 11:24:40.767676",
"modified_by": "Administrator",
"module": "Core",
"name": "Users",
@@ -36,22 +36,22 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "User",
"link_to": "User",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Role",
"link_to": "Role",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "permission-manager",
"link_to": "permission-manager",
"type": "Page"
},
{
- "is_query_report": 0,
+ "label": "user-profile",
"link_to": "user-profile",
"type": "Page"
}
diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py
index ddad3a91fb..7837c90d2b 100644
--- a/frappe/core/doctype/user/user.py
+++ b/frappe/core/doctype/user/user.py
@@ -205,7 +205,7 @@ class User(Document):
_update_password(user=self.name, pwd=new_password,
logout_all_sessions=self.logout_all_sessions)
- if not self.flags.no_welcome_mail and self.send_welcome_email:
+ if not self.flags.no_welcome_mail and cint(self.send_welcome_email):
self.send_welcome_mail_to_user()
self.flags.email_sent = 1
if frappe.session.user != 'Guest':
@@ -577,7 +577,7 @@ def update_password(new_password, logout_all_sessions=0, key=None, old_password=
return redirect_url if redirect_url else "/"
@frappe.whitelist(allow_guest=True)
-def test_password_strength(new_password, key=None, old_password=None, user_data=[]):
+def test_password_strength(new_password, key=None, old_password=None, user_data=None):
from frappe.utils.password_strength import test_password_strength as _test_password_strength
password_policy = frappe.db.get_value("System Settings", None,
diff --git a/frappe/core/page/dashboard/dashboard.js b/frappe/core/page/dashboard/dashboard.js
index 88bfba9e84..ad65b05894 100644
--- a/frappe/core/page/dashboard/dashboard.js
+++ b/frappe/core/page/dashboard/dashboard.js
@@ -97,7 +97,13 @@ class Dashboard {
container: this.container,
type: "chart",
columns: 2,
- allow_sorting: false,
+ options: {
+ allow_sorting: false,
+ allow_create: false,
+ allow_delete: false,
+ allow_hiding: false,
+ allow_edit: false,
+ },
widgets: this.charts,
});
})
diff --git a/frappe/custom/desk_page/customization/customization.json b/frappe/custom/desk_page/customization/customization.json
index dedfcaeeec..29f4cb745f 100644
--- a/frappe/custom/desk_page/customization/customization.json
+++ b/frappe/custom/desk_page/customization/customization.json
@@ -1,17 +1,19 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Dashboard\",\n \"name\": \"Dashboard\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Dashboard Chart\",\n \"name\": \"Dashboard Chart\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Dashboard Chart Source\",\n \"name\": \"Dashboard Chart Source\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Dashboards"
+ "hidden": 0,
+ "label": "Dashboards",
+ "links": "[\n {\n \"label\": \"Dashboard\",\n \"name\": \"Dashboard\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Dashboard Chart\",\n \"name\": \"Dashboard Chart\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Dashboard Chart Source\",\n \"name\": \"Dashboard Chart Source\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-glass",
- "links": "[\n {\n \"description\": \"Change field properties (hide, readonly, permission etc.)\",\n \"label\": \"Customize Form\",\n \"name\": \"Customize Form\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add fields to forms.\",\n \"label\": \"Custom Field\",\n \"name\": \"Custom Field\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add custom javascript to forms.\",\n \"label\": \"Custom Script\",\n \"name\": \"Custom Script\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add custom forms.\",\n \"label\": \"DocType\",\n \"name\": \"DocType\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Form Customization"
+ "hidden": 0,
+ "label": "Form Customization",
+ "links": "[\n {\n \"description\": \"Change field properties (hide, readonly, permission etc.)\",\n \"label\": \"Customize Form\",\n \"name\": \"Customize Form\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add fields to forms.\",\n \"label\": \"Custom Field\",\n \"name\": \"Custom Field\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add custom javascript to forms.\",\n \"label\": \"Custom Script\",\n \"name\": \"Custom Script\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add custom forms.\",\n \"label\": \"DocType\",\n \"name\": \"DocType\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Add your own translations\",\n \"label\": \"Custom Translations\",\n \"name\": \"Translation\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Other"
+ "hidden": 0,
+ "label": "Other",
+ "links": "[\n {\n \"description\": \"Add your own translations\",\n \"label\": \"Custom Translations\",\n \"name\": \"Translation\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Administration",
@@ -25,7 +27,7 @@
"idx": 0,
"is_standard": 1,
"label": "Customization",
- "modified": "2020-03-12 16:30:42.155206",
+ "modified": "2020-04-01 11:24:40.787109",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customization",
@@ -34,17 +36,17 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Customize Form",
"link_to": "Customize Form",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Custom Role",
"link_to": "Custom Role",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Custom Script",
"link_to": "Custom Script",
"type": "DocType"
}
diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.json b/frappe/custom/doctype/customize_form_field/customize_form_field.json
index 57b4cec23b..34778a76e9 100644
--- a/frappe/custom/doctype/customize_form_field/customize_form_field.json
+++ b/frappe/custom/doctype/customize_form_field/customize_form_field.json
@@ -358,7 +358,7 @@
"default": "0",
"fieldname": "allow_in_quick_entry",
"fieldtype": "Check",
- "label": " Allow in Quick Entry "
+ "label": "Allow in Quick Entry"
},
{
"fieldname": "property_depends_on_section",
@@ -385,7 +385,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2020-03-16 14:53:40.619043",
+ "modified": "2020-04-07 14:53:40.619043",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customize Form Field",
diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py
index 1cb03355c6..26bc8c96b3 100644
--- a/frappe/desk/desktop.py
+++ b/frappe/desk/desktop.py
@@ -4,24 +4,34 @@
from __future__ import unicode_literals
import frappe
-import json
-from frappe import _, DoesNotExistError
+from json import loads, dumps
+from frappe import _, DoesNotExistError, ValidationError, _dict
from frappe.boot import get_allowed_pages, get_allowed_reports
from six import string_types
-from frappe.cache_manager import build_domain_restriced_doctype_cache, build_domain_restriced_page_cache, build_table_count_cache
+from frappe.cache_manager import (
+ build_domain_restriced_doctype_cache,
+ build_domain_restriced_page_cache,
+ build_table_count_cache
+)
class Workspace:
def __init__(self, page_name):
self.page_name = page_name
-
- def build_cache(self):
- self.doc = frappe.get_doc("Desk Page", self.page_name)
- self.get_pages_to_extend()
+ self.extended_cards = []
+ self.extended_charts = []
+ self.extended_shortcuts = []
user = frappe.get_user()
user.build_permissions()
- self.user = user
+ user_doc = frappe.get_doc('User', frappe.session.user)
+ self.blocked_modules = user_doc.get_blocked_modules()
+ self.doc = self.get_page_for_user()
+
+ if self.doc.module in self.blocked_modules:
+ raise frappe.PermissionError
+
+ self.user = user
self.allowed_pages = get_allowed_pages()
self.allowed_reports = get_allowed_reports()
@@ -29,16 +39,27 @@ class Workspace:
self.restricted_doctypes = build_domain_restriced_doctype_cache()
self.restricted_pages = build_domain_restriced_page_cache()
+ def get_page_for_user(self):
+ filters = {
+ 'extends': self.page_name,
+ 'for_user': frappe.session.user
+ }
+ pages = frappe.get_list("Desk Page", filters=filters)
+ if pages:
+ return frappe.get_doc("Desk Page", pages[0])
+
+ self.get_pages_to_extend()
+ return frappe.get_doc("Desk Page", self.page_name)
+
def get_pages_to_extend(self):
pages = frappe.get_all("Desk Page", filters={
"extends": self.page_name,
- 'restrict_to_domain': ['in', frappe.get_active_domains()]
+ 'restrict_to_domain': ['in', frappe.get_active_domains()],
+ 'for_user': '',
+ 'module': ['not in', self.blocked_modules]
})
pages = [frappe.get_doc("Desk Page", page['name']) for page in pages]
- self.extended_cards = []
- self.extended_charts = []
- self.extended_shortcuts = []
for page in pages:
self.extended_cards = self.extended_cards + page.cards
@@ -61,17 +82,17 @@ class Workspace:
def build_workspace(self):
self.cards = {
- 'label': self.doc.cards_label,
+ 'label': _(self.doc.cards_label),
'items': self.get_cards()
}
self.charts = {
- 'label': self.doc.charts_label,
+ 'label': _(self.doc.charts_label),
'items': self.get_charts()
}
self.shortcuts = {
- 'label': self.doc.shortcuts_label,
+ 'label': _(self.doc.shortcuts_label),
'items': self.get_shortcuts()
}
@@ -105,18 +126,21 @@ class Workspace:
item["count"] = count
+ # Translate label
+ item["label"] = _(item.label) if item.label else _(item.name)
+
return item
new_data = []
for section in cards:
new_items = []
if isinstance(section.links, string_types):
- links = json.loads(section.links)
+ links = loads(section.links)
else:
links = section.links
for item in links:
- item = frappe._dict(item)
+ item = _dict(item)
# Condition: based on country
if item.country and item.country != default_country:
@@ -125,15 +149,15 @@ class Workspace:
# Check if user is allowed to view
if self.is_item_allowed(item.name, item.type):
prepared_item = _prepare_item(item)
- new_items.append(item)
+ new_items.append(prepared_item)
if new_items:
- if isinstance(section, frappe._dict):
+ if isinstance(section, _dict):
new_section = section.copy()
else:
new_section = section.as_dict().copy()
new_section["links"] = new_items
- new_section["label"] = section.title
+ new_section["label"] = _(new_section["label"])
new_data.append(new_section)
return new_data
@@ -147,7 +171,8 @@ class Workspace:
for chart in charts:
if frappe.has_permission('Dashboard Chart', doc=chart.chart_name):
- chart.label = chart.label if chart.label else chart.chart_name
+ # Translate label
+ chart.label = _(chart.label) if chart.label else _(chart.chart_name)
all_charts.append(chart)
return all_charts
@@ -167,21 +192,23 @@ class Workspace:
for item in shortcuts:
new_item = item.as_dict().copy()
- new_item['name'] = _(item.link_to)
if self.is_item_allowed(item.link_to, item.type) and _in_active_domains(item):
- if item.type == "Page":
- page = self.allowed_pages[item.link_to]
- new_item['label'] = _(page.get("title", frappe.unscrub(item.link_to)))
if item.type == "Report":
report = self.allowed_reports.get(item.link_to, {})
if report.get("report_type") in ["Query Report", "Script Report"]:
new_item['is_query_report'] = 1
+ else:
+ new_item['ref_doctype'] = report.get('ref_doctype')
+
+ # Translate label
+ new_item["label"] = _(item.label) if item.label else _(item.link_to)
items.append(new_item)
return items
@frappe.whitelist()
+@frappe.read_only()
def get_desktop_page(page):
"""Applies permissions, customizations and returns the configruration for a page
on desk.
@@ -192,9 +219,8 @@ def get_desktop_page(page):
Returns:
dict: dictionary of cards, charts and shortcuts to be displayed on website
"""
- wspace = Workspace(page)
try:
- wspace.build_cache()
+ wspace = Workspace(page)
wspace.build_workspace()
return {
'charts': wspace.charts,
@@ -213,9 +239,14 @@ def get_desk_sidebar_items():
"""Get list of sidebar items for desk
"""
# don't get domain restricted pages
+ blocked_modules = frappe.get_doc('User', frappe.session.user).get_blocked_modules()
+
filters = {
'restrict_to_domain': ['in', frappe.get_active_domains()],
- 'extends_another_page': False
+ 'extends_another_page': 0,
+ 'is_standard': 1,
+ 'for_user': '',
+ 'module': ['not in', blocked_modules]
}
if not frappe.local.conf.developer_mode:
@@ -228,8 +259,10 @@ def get_desk_sidebar_items():
from collections import defaultdict
sidebar_items = defaultdict(list)
+ # The order will be maintained while categorizing
for page in pages:
- # The order will be maintained while categorizing
+ # Translate label
+ page['label'] = _(page.get('name'))
sidebar_items[page["category"]].append(page)
return sidebar_items
@@ -242,8 +275,8 @@ def get_table_with_counts():
def get_custom_reports_and_doctypes(module):
return [
- frappe._dict({
- "title": "Custom",
+ _dict({
+ "label": "Custom",
"links": get_custom_doctype_list(module) + get_custom_report_list(module)
})
]
@@ -280,104 +313,111 @@ def get_custom_report_list(module):
return out
-def make_them_pages():
- """Helper function to make pages
+def get_custom_workspace_for_user(page):
+ """Get custom page from desk_page if exists or create one
+
+ Args:
+ page (stirng): Page name
+
+ Returns:
+ Object: Document object
"""
- pages = [
- ('Desk', 'frappe', 'octicon octicon-calendar'),
- ('Settings', 'frappe', 'octicon octicon-settings'),
- ('Users and Permissions', 'frappe', 'octicon octicon-settings'),
- ('Customization', 'frappe', 'octicon octicon-settings'),
- ('Integrations', 'frappe', 'octicon octicon-globe'),
- ('Core', 'frappe', 'octicon octicon-circuit-board'),
- ('Website', 'frappe', 'octicon octicon-globe'),
- ('Getting Started', 'erpnext', 'fa fa-check-square-o'),
- ('Accounts', 'erpnext', 'octicon octicon-repo'),
- ('Selling', 'erpnext', 'octicon octicon-tag'),
- ('Buying', 'erpnext', 'octicon octicon-briefcase'),
- ('Stock', 'erpnext', 'octicon octicon-package'),
- ('Assets', 'erpnext', 'octicon octicon-database'),
- ('Projects', 'erpnext', 'octicon octicon-rocket'),
- ('CRM', 'erpnext', 'octicon octicon-broadcast'),
- ('Support', 'erpnext', 'fa fa-check-square-o'),
- ('HR', 'erpnext', 'octicon octicon-organization'),
- ('Quality Management', 'erpnext', 'fa fa-check-square-o'),
- ('Manufacturing', 'erpnext', 'octicon octicon-tools'),
- ('Retail', 'erpnext', 'octicon octicon-credit-card'),
- ('Education', 'erpnext', 'octicon octicon-mortar-board'),
- ('Healthcare', 'erpnext', 'fa fa-heartbeat'),
- ('Agriculture', 'erpnext', 'octicon octicon-globe'),
- ('Non Profit', 'erpnext', 'octicon octicon-heart'),
- ('Help', 'erpnext', 'octicon octicon-device-camera-video')
- ]
-
- for page in pages:
- print("Processing Page: {0}".format(page[0]))
- make_them_cards(page[0], page[2])
+ filters = {
+ 'extends': page,
+ 'for_user': frappe.session.user
+ }
+ pages = frappe.get_list("Desk Page", filters=filters)
+ if pages:
+ return frappe.get_doc("Desk Page", pages[0])
+ doc = frappe.new_doc("Desk Page")
+ doc.extends = page
+ doc.for_user = frappe.session.user
+ return doc
-def make_them_cards(page_name, from_module=None, to_module=None, icon=None):
- from frappe.desk.moduleview import get
+@frappe.whitelist()
+def save_customization(page, config):
+ """Save customizations as a separate doctype in Desk page per user
- if not from_module:
- from_module = page_name
+ Args:
+ page (string): Name of the page to be edited
+ config (dict): Dictionary config of al widgets
- if not to_module:
- to_module = page_name
+ Returns:
+ Boolean: Customization saving status
+ """
+ original_page = frappe.get_doc("Desk Page", page)
+ page_doc = get_custom_workspace_for_user(page)
+
+ # Update field values
+ page_doc.update({
+ "charts_label": original_page.charts_label,
+ "cards_label": original_page.cards_label,
+ "shortcuts_label": original_page.shortcuts_label,
+ "icon": original_page.icon,
+ "module": original_page.module,
+ "developer_mode_only": original_page.developer_mode_only,
+ "category": original_page.category
+ })
+
+ config = _dict(loads(config))
+ page_doc.charts = prepare_widget(config.charts, "Desk Chart", "charts")
+ page_doc.shortcuts = prepare_widget(config.shortcuts, "Desk Shortcut", "shortcuts")
+ page_doc.cards = prepare_widget(config.cards, "Desk Card", "cards")
+
+ # Set label
+ page_doc.label = page + '-' + frappe.session.user
try:
- modules = get(from_module)['data']
- except:
- return
+ if page_doc.is_new():
+ page_doc.insert(ignore_permissions=True)
+ else:
+ page_doc.save(ignore_permissions=True)
+ except (ValidationError, TypeError) as e:
+ # Create a json string to log
+ json_config = dumps(config, sort_keys=True, indent=4)
- # Find or make page doc
- if frappe.db.exists("Desk Page", page_name):
- page = frappe.get_doc("Desk Page", page_name)
- print("--- Got Page: {0}".format(page.name))
- else:
- page = frappe.new_doc("Desk Page")
- page.label = page_name
- page.cards = []
- page.icon = icon
- print("--- New Page: {0}".format(page.name))
+ # Error log body
+ log = \
+ """
+ page: {0}
+ config: {1}
+ exception: {2}
+ """.format(page, json_config, e)
+ frappe.log_error(log, _("Could not save customization"))
+ return False
- # Guess Which Module
- if not to_module and frappe.db.exists("Module Def", page_name):
- page.module = page_name
+ return True
- if to_module:
- page.module = to_module
- elif frappe.db.exists("Module Def", page_name):
- page.module = page_name
- for data in modules:
- # Create a New Card Child Doc
- card = frappe.new_doc("Desk Card")
+def prepare_widget(config, doctype, parentfield):
+ """Create widget child table entries with parent details
- # Data clean up
- for item in data['items']:
- try:
- del item['count']
- del item['incomplete_dependencies']
- except KeyError:
- pass
+ Args:
+ config (dict): Dictionary containing widget config
+ doctype (string): Doctype name of the child table
+ parentfield (string): Parent field for the child table
- # Set Child doc values
- card.title = data['label']
- card.icon = data.get('icon')
- # Pretty dump JSON
- card.links = json.dumps(data['items'], indent=4, sort_keys=True)
+ Returns:
+ TYPE: List of Document objects
+ """
+ order = config.get('order')
+ widgets = config.get('widgets')
+ prepare_widget_list = []
+ for idx, name in enumerate(order):
+ wid_config = widgets[name].copy()
+ # Some cleanup
+ wid_config.pop("name", None)
- # Set Parent attributes
- card.parent = page.name
- card.parenttype = page.doctype
- card.parentfield = "cards"
+ # New Doc
+ doc = frappe.new_doc(doctype)
+ doc.update(wid_config)
- # Add cards to page doc
- print("------- Adding Card: {0}".format(card.title))
- page.cards.append(card)
+ # Manually Set IDX
+ doc.idx = idx + 1
- # End it all
- page.save()
- frappe.db.commit()
- return
\ No newline at end of file
+ # Set Parent Field
+ doc.parentfield = parentfield
+
+ prepare_widget_list.append(doc)
+ return prepare_widget_list
diff --git a/frappe/desk/doctype/desk_card/desk_card.json b/frappe/desk/doctype/desk_card/desk_card.json
index 4ccffd4f58..dbcb4b0d5c 100644
--- a/frappe/desk/doctype/desk_card/desk_card.json
+++ b/frappe/desk/doctype/desk_card/desk_card.json
@@ -2,11 +2,12 @@
"actions": [],
"creation": "2020-01-29 14:45:54.383089",
"doctype": "DocType",
+ "editable_grid": 1,
"engine": "InnoDB",
"field_order": [
- "title",
+ "label",
"column_break_2",
- "icon",
+ "hidden",
"section_break_3",
"links"
],
@@ -18,13 +19,6 @@
"options": "JSON",
"reqd": 1
},
- {
- "fieldname": "title",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Title",
- "reqd": 1
- },
{
"fieldname": "section_break_3",
"fieldtype": "Section Break"
@@ -34,14 +28,23 @@
"fieldtype": "Column Break"
},
{
- "fieldname": "icon",
+ "default": "0",
+ "fieldname": "hidden",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Hidden"
+ },
+ {
+ "fieldname": "label",
"fieldtype": "Data",
- "label": "Icon"
+ "in_list_view": 1,
+ "label": "Label",
+ "reqd": 1
}
],
"istable": 1,
"links": [],
- "modified": "2020-02-03 12:40:42.595122",
+ "modified": "2020-03-31 14:38:06.303847",
"modified_by": "Administrator",
"module": "Desk",
"name": "Desk Card",
diff --git a/frappe/desk/doctype/desk_chart/desk_chart.json b/frappe/desk/doctype/desk_chart/desk_chart.json
index c3c9231353..09deefd59d 100644
--- a/frappe/desk/doctype/desk_chart/desk_chart.json
+++ b/frappe/desk/doctype/desk_chart/desk_chart.json
@@ -26,7 +26,7 @@
],
"istable": 1,
"links": [],
- "modified": "2020-03-20 10:04:13.992228",
+ "modified": "2020-03-31 13:33:13.128804",
"modified_by": "Administrator",
"module": "Desk",
"name": "Desk Chart",
diff --git a/frappe/desk/doctype/desk_page/desk_page.js b/frappe/desk/doctype/desk_page/desk_page.js
index 7af3e0e98c..3087a5f5b8 100644
--- a/frappe/desk/doctype/desk_page/desk_page.js
+++ b/frappe/desk/doctype/desk_page/desk_page.js
@@ -2,17 +2,21 @@
// For license information, please see license.txt
frappe.ui.form.on('Desk Page', {
- refresh: function(frm) {
+ setup: function(frm) {
frm.get_field("is_standard").toggle(frappe.boot.developer_mode);
frm.get_field("extends_another_page").toggle(frappe.boot.developer_mode);
- if (!frappe.boot.developer_mode) {
- frm.set_read_only();
- frm.fields
- .filter(field => field.has_input)
- .forEach(field => {
- frm.set_df_property(field.df.fieldname, "read_only", "1");
- });
- frm.disable_save();
+ if (!frappe.boot.developer_mode || frm.doc.for_user) {
+ frm.trigger('disable_form');
}
+ },
+
+ disable_form: function(frm) {
+ frm.set_read_only();
+ frm.fields
+ .filter(field => field.has_input)
+ .forEach(field => {
+ frm.set_df_property(field.df.fieldname, "read_only", "1");
+ });
+ frm.disable_save();
}
-});
+});
\ No newline at end of file
diff --git a/frappe/desk/doctype/desk_page/desk_page.json b/frappe/desk/doctype/desk_page/desk_page.json
index 6bc33d1326..7e6baf221b 100644
--- a/frappe/desk/doctype/desk_page/desk_page.json
+++ b/frappe/desk/doctype/desk_page/desk_page.json
@@ -9,6 +9,7 @@
"field_order": [
"label",
"extends",
+ "for_user",
"module",
"category",
"restrict_to_domain",
@@ -36,7 +37,6 @@
"fieldname": "label",
"fieldtype": "Data",
"label": "Name",
- "length": 22,
"unique": 1
},
{
@@ -52,6 +52,7 @@
"options": "Desk Chart"
},
{
+ "depends_on": "eval:!doc.extends_another_page || !doc.is_standard",
"fieldname": "shortcuts",
"fieldtype": "Table",
"label": "Shortcuts",
@@ -136,16 +137,19 @@
"search_index": 1
},
{
+ "depends_on": "eval:!doc.extends_another_page || !doc.is_standard",
"fieldname": "charts_label",
"fieldtype": "Data",
"label": "Label"
},
{
+ "depends_on": "eval:!doc.extends_another_page || !doc.is_standard",
"fieldname": "shortcuts_label",
"fieldtype": "Data",
"label": "Label"
},
{
+ "depends_on": "eval:!doc.extends_another_page || !doc.is_standard",
"fieldname": "cards_label",
"fieldtype": "Data",
"label": "Label"
@@ -166,24 +170,36 @@
"default": "0",
"fieldname": "is_standard",
"fieldtype": "Check",
- "label": "Is Standard"
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Is Standard",
+ "search_index": 1
},
{
"default": "0",
"fieldname": "extends_another_page",
"fieldtype": "Check",
- "label": "Extends Another Page"
+ "label": "Extends Another Page",
+ "search_index": 1
},
{
"depends_on": "eval:doc.extends_another_page == 1",
"fieldname": "extends",
"fieldtype": "Link",
+ "in_standard_filter": 1,
"label": "Extends",
- "options": "Desk Page"
+ "options": "Desk Page",
+ "search_index": 1
+ },
+ {
+ "fieldname": "for_user",
+ "fieldtype": "Data",
+ "label": "For User",
+ "read_only": 1
}
],
"links": [],
- "modified": "2020-03-12 16:38:16.206732",
+ "modified": "2020-03-26 12:35:41.981432",
"modified_by": "Administrator",
"module": "Desk",
"name": "Desk Page",
diff --git a/frappe/desk/doctype/desk_shortcut/desk_shortcut.json b/frappe/desk/doctype/desk_shortcut/desk_shortcut.json
index 6b57f250a9..9f8990732a 100644
--- a/frappe/desk/doctype/desk_shortcut/desk_shortcut.json
+++ b/frappe/desk/doctype/desk_shortcut/desk_shortcut.json
@@ -6,11 +6,11 @@
"engine": "InnoDB",
"field_order": [
"type",
- "icon",
+ "label",
"column_break_4",
"link_to",
+ "icon",
"restrict_to_domain",
- "is_query_report",
"section_break_5",
"stats_filter",
"column_break_3",
@@ -51,6 +51,7 @@
"label": "Format"
},
{
+ "depends_on": "eval:doc.type == \"DocType\" && frappe.boot.developer_mode",
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"label": "Count Filter"
@@ -61,13 +62,7 @@
"label": "Color"
},
{
- "default": "0",
- "depends_on": "eval:doc.type === \"Report\"",
- "fieldname": "is_query_report",
- "fieldtype": "Check",
- "label": "Is Query Report"
- },
- {
+ "depends_on": "eval:frappe.boot.developer_mode",
"fieldname": "icon",
"fieldtype": "Data",
"label": "Icon"
@@ -77,15 +72,22 @@
"fieldtype": "Column Break"
},
{
+ "depends_on": "eval:frappe.boot.developer_mode",
"fieldname": "restrict_to_domain",
"fieldtype": "Link",
"label": "Restrict to Domain",
"options": "Domain"
+ },
+ {
+ "fieldname": "label",
+ "fieldtype": "Data",
+ "label": "Label",
+ "reqd": 1
}
],
"istable": 1,
"links": [],
- "modified": "2020-03-11 13:09:00.180528",
+ "modified": "2020-04-07 19:04:23.645198",
"modified_by": "Administrator",
"module": "Desk",
"name": "Desk Shortcut",
diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py
index 2d40ffd800..2469569892 100755
--- a/frappe/email/doctype/newsletter/newsletter.py
+++ b/frappe/email/doctype/newsletter/newsletter.py
@@ -51,9 +51,6 @@ class Newsletter(WebsiteGenerator):
frappe.msgprint(_("Scheduled to send to {0} recipients").format(len(self.recipients)))
- frappe.db.set(self, "email_sent", 1)
- frappe.db.set(self, "schedule_send", now_datetime())
- frappe.db.set(self, 'scheduled_to_send', len(self.recipients))
else:
frappe.msgprint(_("Newsletter should have atleast one recipient"))
@@ -71,8 +68,8 @@ class Newsletter(WebsiteGenerator):
attachments = []
if self.send_attachements:
- files = frappe.get_all("File", fields = ["name"], filters = {"attached_to_doctype": "Newsletter",
- "attached_to_name":self.name}, order_by="creation desc")
+ files = frappe.get_all("File", fields=["name"], filters={"attached_to_doctype": "Newsletter",
+ "attached_to_name": self.name}, order_by="creation desc")
for file in files:
try:
@@ -82,17 +79,21 @@ class Newsletter(WebsiteGenerator):
except IOError:
frappe.throw(_("Unable to find attachment {0}").format(file.name))
- send(recipients = self.recipients, sender = sender,
- subject = self.subject, message = self.message,
- reference_doctype = self.doctype, reference_name = self.name,
- add_unsubscribe_link = self.send_unsubscribe_link, attachments=attachments,
- unsubscribe_method = "/unsubscribe",
- unsubscribe_params = {"name": self.name},
- send_priority = 0, queue_separately=True)
+ send(recipients=self.recipients, sender=sender,
+ subject=self.subject, message=self.message,
+ reference_doctype=self.doctype, reference_name=self.name,
+ add_unsubscribe_link=self.send_unsubscribe_link, attachments=attachments,
+ unsubscribe_method="/unsubscribe",
+ unsubscribe_params={"name": self.name},
+ send_priority=0, queue_separately=True)
if not frappe.flags.in_test:
frappe.db.auto_commit_on_many_writes = False
+ self.db_set("email_sent", 1)
+ self.db_set("schedule_send", now_datetime())
+ self.db_set("scheduled_to_send", len(self.recipients))
+
def get_recipients(self):
"""Get recipients from Email Group"""
recipients_list = []
@@ -268,6 +269,6 @@ def send_scheduled_email():
scheduled_newsletter = frappe.get_all('Newsletter', filters = {
'schedule_send': ('<=', now_datetime()),
'email_sent': 0
- }, fields = ['name'])
+ }, fields = ['name'], ignore_ifnull=True)
for newsletter in scheduled_newsletter:
- send_newsletter(newsletter.name)
\ No newline at end of file
+ send_newsletter(newsletter.name)
diff --git a/frappe/integrations/desk_page/integrations/integrations.json b/frappe/integrations/desk_page/integrations/integrations.json
index 6ea871cd90..9201e223f8 100644
--- a/frappe/integrations/desk_page/integrations/integrations.json
+++ b/frappe/integrations/desk_page/integrations/integrations.json
@@ -1,25 +1,29 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Dropbox backup settings\",\n \"label\": \"Dropbox Settings\",\n \"name\": \"Dropbox Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"S3 Backup Settings\",\n \"label\": \"S3 Backup Settings\",\n \"name\": \"S3 Backup Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Drive Backup.\",\n \"label\": \"Google Drive\",\n \"name\": \"Google Drive\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Backup"
+ "hidden": 0,
+ "label": "Backup",
+ "links": "[\n {\n \"description\": \"Dropbox backup settings\",\n \"label\": \"Dropbox Settings\",\n \"name\": \"Dropbox Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"S3 Backup Settings\",\n \"label\": \"S3 Backup Settings\",\n \"name\": \"S3 Backup Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Drive Backup.\",\n \"label\": \"Google Drive\",\n \"name\": \"Google Drive\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Google API Settings.\",\n \"label\": \"Google Settings\",\n \"name\": \"Google Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Contacts Integration.\",\n \"label\": \"Google Contacts\",\n \"name\": \"Google Contacts\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Calendar Integration.\",\n \"label\": \"Google Calendar\",\n \"name\": \"Google Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Drive Integration.\",\n \"label\": \"Google Drive\",\n \"name\": \"Google Drive\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Google Services"
+ "hidden": 0,
+ "label": "Google Services",
+ "links": "[\n {\n \"description\": \"Google API Settings.\",\n \"label\": \"Google Settings\",\n \"name\": \"Google Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Contacts Integration.\",\n \"label\": \"Google Contacts\",\n \"name\": \"Google Contacts\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Calendar Integration.\",\n \"label\": \"Google Calendar\",\n \"name\": \"Google Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Google Drive Integration.\",\n \"label\": \"Google Drive\",\n \"name\": \"Google Drive\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Webhooks calling API requests into web apps\",\n \"label\": \"Webhook\",\n \"name\": \"Webhook\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Slack Webhooks for internal integration\",\n \"label\": \"Slack Webhook URL\",\n \"name\": \"Slack Webhook URL\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Webhook"
+ "hidden": 0,
+ "label": "Webhook",
+ "links": "[\n {\n \"description\": \"Webhooks calling API requests into web apps\",\n \"label\": \"Webhook\",\n \"name\": \"Webhook\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Slack Webhooks for internal integration\",\n \"label\": \"Slack Webhook URL\",\n \"name\": \"Slack Webhook URL\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Enter keys to enable login via Facebook, Google, GitHub.\",\n \"label\": \"Social Login Key\",\n \"name\": \"Social Login Key\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Ldap settings\",\n \"label\": \"LDAP Settings\",\n \"name\": \"LDAP Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Register OAuth Client App\",\n \"label\": \"OAuth Client\",\n \"name\": \"OAuth Client\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for OAuth Provider\",\n \"label\": \"OAuth Provider Settings\",\n \"name\": \"OAuth Provider Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Authentication"
+ "hidden": 0,
+ "label": "Authentication",
+ "links": "[\n {\n \"description\": \"Enter keys to enable login via Facebook, Google, GitHub.\",\n \"label\": \"Social Login Key\",\n \"name\": \"Social Login Key\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Ldap settings\",\n \"label\": \"LDAP Settings\",\n \"name\": \"LDAP Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Register OAuth Client App\",\n \"label\": \"OAuth Client\",\n \"name\": \"OAuth Client\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Settings for OAuth Provider\",\n \"label\": \"OAuth Provider Settings\",\n \"name\": \"OAuth Provider Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Braintree payment gateway settings\",\n \"label\": \"Braintree Settings\",\n \"name\": \"Braintree Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"PayPal payment gateway settings\",\n \"label\": \"PayPal Settings\",\n \"name\": \"PayPal Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Razorpay Payment gateway settings\",\n \"label\": \"Razorpay Settings\",\n \"name\": \"Razorpay Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Stripe payment gateway settings\",\n \"label\": \"Stripe Settings\",\n \"name\": \"Stripe Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Payments"
+ "hidden": 0,
+ "label": "Payments",
+ "links": "[\n {\n \"description\": \"Braintree payment gateway settings\",\n \"label\": \"Braintree Settings\",\n \"name\": \"Braintree Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"PayPal payment gateway settings\",\n \"label\": \"PayPal Settings\",\n \"name\": \"PayPal Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Razorpay Payment gateway settings\",\n \"label\": \"Razorpay Settings\",\n \"name\": \"Razorpay Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Stripe payment gateway settings\",\n \"label\": \"Stripe Settings\",\n \"name\": \"Stripe Settings\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Administration",
@@ -34,7 +38,7 @@
"idx": 0,
"is_standard": 1,
"label": "Integrations",
- "modified": "2020-03-12 16:30:42.823316",
+ "modified": "2020-04-01 11:24:40.751651",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Integrations",
diff --git a/frappe/integrations/doctype/oauth_client/oauth_client.json b/frappe/integrations/doctype/oauth_client/oauth_client.json
index 47ede6e280..d0d45c36ab 100644
--- a/frappe/integrations/doctype/oauth_client/oauth_client.json
+++ b/frappe/integrations/doctype/oauth_client/oauth_client.json
@@ -1,517 +1,517 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "",
- "beta": 0,
- "creation": "2016-08-24 14:07:21.955052",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "",
+ "beta": 0,
+ "creation": "2016-08-24 14:07:21.955052",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "client_id",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "App Client ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "client_id",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "App Client ID",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "app_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "App Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "app_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "App Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "user",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "User",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "User",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb_1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "client_secret",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "App Client Secret",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "client_secret",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "App Client Secret",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "If checked, users will not see the Confirm Access dialog.",
- "fieldname": "skip_authorization",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Skip Authorization",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "If checked, users will not see the Confirm Access dialog.",
+ "fieldname": "skip_authorization",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Skip Authorization",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fieldname": "sb_1",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "sb_1",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "all openid",
- "description": "A list of resources which the Client App will have access to after the user allows it.
e.g. project",
- "fieldname": "scopes",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Scopes",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "all openid",
+ "description": "A list of resources which the Client App will have access to after the user allows it.
e.g. project",
+ "fieldname": "scopes",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Scopes",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "URIs for receiving authorization code once the user allows access, as well as failure responses. Typically a REST endpoint exposed by the Client App.\n
e.g. http://hostname//api/method/frappe.www.login.login_via_facebook",
- "fieldname": "redirect_uris",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Redirect URIs",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "URIs for receiving authorization code once the user allows access, as well as failure responses. Typically a REST endpoint exposed by the Client App.\n
e.g. http://hostname//api/method/frappe.www.login.login_via_facebook",
+ "fieldname": "redirect_uris",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Redirect URIs",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_redirect_uri",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Redirect URI",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_redirect_uri",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Redirect URI",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "collapsible_depends_on": "1",
- "columns": 0,
- "fieldname": "sb_advanced",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": " Advanced Settings",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "collapsible_depends_on": "1",
+ "columns": 0,
+ "fieldname": "sb_advanced",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Advanced Settings",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "grant_type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Grant Type",
- "length": 0,
- "no_copy": 0,
- "options": "Authorization Code\nImplicit",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "grant_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Grant Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Authorization Code\nImplicit",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Code",
- "fieldname": "response_type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Response Type",
- "length": 0,
- "no_copy": 0,
- "options": "Code\nToken",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Code",
+ "fieldname": "response_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Response Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Code\nToken",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-10-05 21:07:39.476360",
- "modified_by": "Administrator",
- "module": "Integrations",
- "name": "OAuth Client",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2020-04-07 21:07:39.476360",
+ "modified_by": "Administrator",
+ "module": "Integrations",
+ "name": "OAuth Client",
+ "name_case": "",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "app_name",
- "track_changes": 1,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "app_name",
+ "track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/frappe/model/naming.py b/frappe/model/naming.py
index 78d2c462e1..ffaf84e2b3 100644
--- a/frappe/model/naming.py
+++ b/frappe/model/naming.py
@@ -110,7 +110,11 @@ def make_autoname(key="", doctype="", doc=""):
if "#" not in key:
key = key + ".#####"
elif "." not in key:
- frappe.throw(_("Invalid naming series (. missing)") + (_(" for {0}").format(doctype) if doctype else ""))
+ error_message = _("Invalid naming series (. missing)")
+ if doctype:
+ error_message = _("Invalid naming series (. missing) for {0}").format(doctype)
+
+ frappe.throw(error_message)
parts = key.split('.')
n = parse_naming_series(parts, doctype, doc)
diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js
index 0e36e671cc..31d62dc445 100644
--- a/frappe/public/js/frappe/form/grid_row.js
+++ b/frappe/public/js/frappe/form/grid_row.js
@@ -550,6 +550,7 @@ export default class GridRow {
hide_form() {
frappe.dom.unfreeze();
this.row.toggle(true);
+ frappe.utils.scroll_to(this.row, true, 15);
this.refresh();
if(cur_frm) cur_frm.cur_grid = null;
this.wrapper.removeClass("grid-row-open");
diff --git a/frappe/public/js/frappe/form/grid_row_form.js b/frappe/public/js/frappe/form/grid_row_form.js
index 73f0856c08..f93640936f 100644
--- a/frappe/public/js/frappe/form/grid_row_form.js
+++ b/frappe/public/js/frappe/form/grid_row_form.js
@@ -9,6 +9,7 @@ export default class GridRowForm {
var me = this;
this.make_form();
this.form_area.empty();
+ frappe.utils.scroll_to(0, false, 0, this.wrapper.find('.grid-form-body'));
this.layout = new frappe.ui.form.Layout({
fields: this.row.docfields,
diff --git a/frappe/public/js/frappe/form/workflow.js b/frappe/public/js/frappe/form/workflow.js
index 4eb33a5f28..4c59e8219b 100644
--- a/frappe/public/js/frappe/form/workflow.js
+++ b/frappe/public/js/frappe/form/workflow.js
@@ -29,20 +29,18 @@ frappe.ui.form.States = Class.extend({
});
frappe.workflow.get_transitions(me.frm.doc).then((transitions) => {
- var next_html = $.map(transitions,
- function(d) {
- return d.action.bold() + __(" by Role ") + d.allowed;
- }).join(", ") || __("None: End of Workflow").bold();
+ const next_actions = $.map(transitions, d => `${d.action.bold()} ${__("by Role")} ${d.allowed}`)
+ .join(", ") || __("None: End of Workflow").bold();
+
+ const document_editable_by = frappe.workflow.get_document_state(me.frm.doctype, state).allow_edit.bold();
+
+ $(d.body).html(`
+
${__("Current status")}: ${state.bold()}
+${__("Document is only editable by users with role")}: ${document_editable_by}
+${__("Next actions")}: ${next_actions}
+${__("{0}: Other permission rules may also apply", [__('Note').bold()])}
+ `).css({padding: '15px'}); - $(d.body).html(""+__("Current status")+": " + state.bold() + "
" - + ""+__("Document is only editable by users of role")+": " - + frappe.workflow.get_document_state(me.frm.doctype, - state).allow_edit.bold() + "
" - + ""+__("Next actions")+": "+ next_html +"
" - + (me.frm.doc.__islocal ? (""+__("Note: Other permission rules may also apply")+"
" - ).css({padding: '15px'}); d.show(); }); }, true); @@ -115,7 +113,7 @@ frappe.ui.form.States = Class.extend({ } else { this.setup_btn(added); } - + }); }, diff --git a/frappe/public/js/frappe/list/list_sidebar_group_by.js b/frappe/public/js/frappe/list/list_sidebar_group_by.js index bd37b71ae4..7aa62dcb5f 100644 --- a/frappe/public/js/frappe/list/list_sidebar_group_by.js +++ b/frappe/public/js/frappe/list/list_sidebar_group_by.js @@ -53,15 +53,18 @@ frappe.views.ListGroupBy = class ListGroupBy { render_group_by_items() { let get_item_html = (fieldname) => { - let label; - let fieldtype; + let label, fieldtype; if (fieldname === 'assigned_to') { label = __('Assigned To'); } else if (fieldname === 'owner') { label = __('Created By'); } else { label = frappe.meta.get_label(this.doctype, fieldname); - fieldtype = frappe.meta.get_docfield(this.doctype, fieldname).fieldtype; + let docfield = frappe.meta.get_docfield(this.doctype, fieldname); + if (!docfield) { + return; + } + fieldtype = docfield.fieldtype; } return `