Merge branch 'develop' into feat-frontmatter
This commit is contained in:
commit
9a3c8aaee5
69 changed files with 2475 additions and 2691 deletions
|
|
@ -5,7 +5,7 @@
|
|||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8,
|
||||
"ecmaVersion": 9,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
|
|
|
|||
16
.github/workflows/backport.yml
vendored
16
.github/workflows/backport.yml
vendored
|
|
@ -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 }}
|
||||
|
|
@ -3,15 +3,16 @@
|
|||
# These owners will be the default owners for everything in
|
||||
# the repo. Unless a later match takes precedence,
|
||||
|
||||
* @surajshetty3416, @netchampfaris
|
||||
* @frappe/frappe-review-team
|
||||
website/ @scmmishra
|
||||
web_form/ @scmmishra
|
||||
templates/ @scmmishra
|
||||
www/ @scmmishra
|
||||
integrations/ @Mangesh-Khairnar
|
||||
patches/ @surajshetty3416 @sahil28297
|
||||
patches/ @sahil28297
|
||||
dashboard/ @prssanna
|
||||
email/ @Thunderbottom
|
||||
event_streaming/ @ruchamahabal
|
||||
data_import* @netchampfaris
|
||||
core/ @surajshetty3416
|
||||
requirements.txt @gavindsouza
|
||||
requirements.txt @gavindsouza
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"actions": [],
|
||||
"allow_events_in_timeline": 1,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
|
|
@ -115,6 +116,7 @@
|
|||
"label": "Phone",
|
||||
"oldfieldname": "contact_no",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Phone",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -200,6 +202,7 @@
|
|||
"fieldname": "mobile_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Mobile No",
|
||||
"options": "Phone",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -245,7 +248,8 @@
|
|||
"icon": "fa fa-user",
|
||||
"idx": 1,
|
||||
"image_field": "image",
|
||||
"modified": "2019-10-10 22:04:41.070479",
|
||||
"links": [],
|
||||
"modified": "2020-04-06 18:25:28.223693",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Contacts",
|
||||
"name": "Contact",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"actions": [],
|
||||
"creation": "2019-08-02 13:10:37.890214",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Number",
|
||||
"options": "Phone",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -34,7 +36,8 @@
|
|||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-09-24 17:47:50.375326",
|
||||
"links": [],
|
||||
"modified": "2020-04-06 18:28:10.486220",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Contacts",
|
||||
"name": "Contact Phone",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,12 +238,14 @@
|
|||
{
|
||||
"fieldname": "phone",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone"
|
||||
"label": "Phone",
|
||||
"options": "Phone"
|
||||
},
|
||||
{
|
||||
"fieldname": "mobile_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Mobile No",
|
||||
"options": "Phone",
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -588,7 +590,7 @@
|
|||
"image_field": "user_image",
|
||||
"links": [],
|
||||
"max_attachments": 5,
|
||||
"modified": "2020-03-23 22:59:26.154985",
|
||||
"modified": "2020-04-08 12:27:36.716490",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1,201 +1,63 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-03-30 10:04:25.828742",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"actions": [],
|
||||
"creation": "2016-03-30 10:04:25.828742",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"email_account",
|
||||
"email_id",
|
||||
"column_break_3",
|
||||
"awaiting_password",
|
||||
"enable_outgoing"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "email_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Email Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Email Account",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "email_account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Email Account",
|
||||
"options": "Email Account",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "email_account.email_id",
|
||||
"fieldname": "email_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": "Email ID",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "email_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Email ID",
|
||||
"options": "Email",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "email_account.awaiting_password",
|
||||
"fieldname": "awaiting_password",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Awaiting Password",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "0",
|
||||
"fetch_from": "email_account.awaiting_password",
|
||||
"fieldname": "awaiting_password",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Awaiting Password",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "email_account.enable_outgoing",
|
||||
"fieldname": "enable_outgoing",
|
||||
"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": "Enable Outgoing",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"default": "0",
|
||||
"fetch_from": "email_account.enable_outgoing",
|
||||
"fieldname": "enable_outgoing",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Outgoing",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-05-25 22:43:34.045787",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User Email",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-04-06 19:19:12.130246",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User Email",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
|
|
@ -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,
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
# Set Parent Field
|
||||
doc.parentfield = parentfield
|
||||
|
||||
prepare_widget_list.append(doc)
|
||||
return prepare_widget_list
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@
|
|||
"fieldname": "chart_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Chart Type",
|
||||
"options": "Count\nSum\nAverage\nGroup By\nCustom\nReport"
|
||||
"options": "Count\nSum\nAverage\nGroup By\nCustom\nReport",
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.chart_type === 'Custom'",
|
||||
|
|
@ -215,7 +216,7 @@
|
|||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-03-31 16:00:01.987059",
|
||||
"modified": "2020-04-08 18:54:36.739183",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Dashboard Chart",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -8,5 +8,14 @@ frappe.ui.form.on('Notification Settings', {
|
|||
route: '#modules/Settings',
|
||||
type: 'Custom'
|
||||
});
|
||||
},
|
||||
|
||||
refresh: (frm) => {
|
||||
if (frappe.user.has_role('System Manager')) {
|
||||
frm.add_custom_button('Go to Notification Settings List', () => {
|
||||
frappe.set_route('List', 'Notification Settings');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,7 +62,14 @@ def get_subscribed_documents():
|
|||
def get_permission_query_conditions(user):
|
||||
if not user: user = frappe.session.user
|
||||
|
||||
return '''(`tabNotification Settings`.user = '{user}')'''.format(user=user)
|
||||
if user == 'Administrator':
|
||||
return
|
||||
|
||||
roles = frappe.get_roles(user)
|
||||
if "System Manager" in roles:
|
||||
return '''(`tabNotification Settings`.name != 'Administrator')'''
|
||||
|
||||
return '''(`tabNotification Settings`.name = '{user}')'''.format(user=user)
|
||||
|
||||
@frappe.whitelist()
|
||||
def set_seen_value(value, user):
|
||||
|
|
|
|||
31
frappe/desk/doctype/todo/todo_calendar.js
Normal file
31
frappe/desk/doctype/todo/todo_calendar.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.views.calendar["ToDo"] = {
|
||||
field_map: {
|
||||
"start": "date",
|
||||
"end": "date",
|
||||
"id": "name",
|
||||
"title": "description",
|
||||
"allDay": "allDay",
|
||||
"progress": "progress"
|
||||
},
|
||||
gantt: true,
|
||||
filters: [
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "reference_type",
|
||||
"options": "Task",
|
||||
"label": __("Task")
|
||||
},
|
||||
{
|
||||
"fieldtype": "Dynamic Link",
|
||||
"fieldname": "reference_name",
|
||||
"options": "reference_type",
|
||||
"label": __("Task")
|
||||
}
|
||||
|
||||
],
|
||||
get_events_method: "frappe.desk.calendar.get_events"
|
||||
};
|
||||
|
||||
|
|
@ -8,16 +8,22 @@ from frappe import _
|
|||
from frappe.desk.doctype.global_search_settings.global_search_settings import update_global_search_doctypes
|
||||
|
||||
def install():
|
||||
update_genders_and_salutations()
|
||||
update_genders()
|
||||
update_salutations()
|
||||
update_global_search_doctypes()
|
||||
setup_email_linking()
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_genders_and_salutations():
|
||||
default_genders = [_("Male"), _("Female"), _("Other")]
|
||||
default_salutations = [_("Mr"), _("Ms"), _('Mx'), _("Dr"), _("Mrs"), _("Madam"), _("Miss"), _("Master"), _("Prof")]
|
||||
def update_genders():
|
||||
default_genders = [_("Male"), _("Female"), _("Other"),_("Transgender"), _("Genderqueer"), _("Non-Conforming"),_("Prefer not to say")]
|
||||
records = [{'doctype': 'Gender', 'gender': d} for d in default_genders]
|
||||
records += [{'doctype': 'Salutation', 'salutation': d} for d in default_salutations]
|
||||
for record in records:
|
||||
frappe.get_doc(record).insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_salutations():
|
||||
default_salutations = [_("Mr"), _("Ms"), _('Mx'), _("Dr"), _("Mrs"), _("Madam"), _("Miss"), _("Master"), _("Prof")]
|
||||
records = [{'doctype': 'Salutation', 'salutation': d} for d in default_salutations]
|
||||
for record in records:
|
||||
doc = frappe.new_doc(record.get("doctype"))
|
||||
doc.update(record)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"label": "Email Address",
|
||||
"options": "Email",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -410,7 +411,7 @@
|
|||
],
|
||||
"icon": "fa fa-inbox",
|
||||
"links": [],
|
||||
"modified": "2019-12-18 15:56:39.744520",
|
||||
"modified": "2020-04-06 19:20:50.491146",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Email",
|
||||
"name": "Email Account",
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ def add_subscribers(name, email_list):
|
|||
email_list = email_list.replace(",", "\n").split("\n")
|
||||
|
||||
template = frappe.db.get_value('Email Group', name, 'welcome_email_template')
|
||||
if template:
|
||||
welcome_email = frappe.get_doc("Email Template", template)
|
||||
welcome_email = frappe.get_doc("Email Template", template) if template else None
|
||||
|
||||
count = 0
|
||||
for email in email_list:
|
||||
|
|
@ -108,4 +107,4 @@ def send_welcome_email(welcome_email, email, email_group):
|
|||
)
|
||||
|
||||
message = frappe.render_template(welcome_email.response, args)
|
||||
frappe.sendmail(email, subject=welcome_email.subject, message=message)
|
||||
frappe.sendmail(email, subject=welcome_email.subject, message=message)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
send_newsletter(newsletter.name)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1,487 +1,129 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-09-21 10:12:57.399174",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"editable_grid": 1,
|
||||
"creation": "2016-09-21 10:12:57.399174",
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"editable_grid": 1,
|
||||
"field_order": [
|
||||
"enabled",
|
||||
"send_notifications_to",
|
||||
"send_email_for_successful_backup",
|
||||
"backup_frequency",
|
||||
"limit_no_of_backups",
|
||||
"no_of_backups",
|
||||
"file_backup",
|
||||
"app_access_key",
|
||||
"app_secret_key",
|
||||
"allow_dropbox_access",
|
||||
"dropbox_access_key",
|
||||
"dropbox_access_secret",
|
||||
"dropbox_access_token"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "enabled",
|
||||
"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": "Enabled",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "0",
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "send_notifications_to",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Send Notifications To",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "send_notifications_to",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Send Notifications To",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"description": "Note: By default emails for failed backups are sent.",
|
||||
"fieldname": "send_email_for_successful_backup",
|
||||
"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": "Send Email for Successful Backup",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "1",
|
||||
"description": "Note: By default emails for failed backups are sent.",
|
||||
"fieldname": "send_email_for_successful_backup",
|
||||
"fieldtype": "Check",
|
||||
"label": "Send Email for Successful Backup"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "backup_frequency",
|
||||
"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": 0,
|
||||
"label": "Backup Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDaily\nWeekly",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "backup_frequency",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Backup Frequency",
|
||||
"options": "\nDaily\nWeekly",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "limit_no_of_backups",
|
||||
"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": "Limit Number of DB Backups",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "0",
|
||||
"fieldname": "limit_no_of_backups",
|
||||
"fieldtype": "Check",
|
||||
"label": "Limit Number of DB Backups"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "5",
|
||||
"depends_on": "eval:doc.limit_no_of_backups",
|
||||
"fieldname": "no_of_backups",
|
||||
"fieldtype": "Int",
|
||||
"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": "Number of DB Backups",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "5",
|
||||
"depends_on": "eval:doc.limit_no_of_backups",
|
||||
"fieldname": "no_of_backups",
|
||||
"fieldtype": "Int",
|
||||
"label": "Number of DB Backups"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fieldname": "file_backup",
|
||||
"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": "File Backup",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "1",
|
||||
"fieldname": "file_backup",
|
||||
"fieldtype": "Check",
|
||||
"label": "File Backup"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "app_access_key",
|
||||
"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 Access Key",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "app_access_key",
|
||||
"fieldtype": "Data",
|
||||
"label": "App Access Key"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "app_secret_key",
|
||||
"fieldtype": "Password",
|
||||
"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 Secret Key",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "app_secret_key",
|
||||
"fieldtype": "Password",
|
||||
"label": "App Secret Key"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_dropbox_access",
|
||||
"fieldtype": "Button",
|
||||
"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": "Allow Dropbox Access",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "allow_dropbox_access",
|
||||
"fieldtype": "Button",
|
||||
"label": "Allow Dropbox Access"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "dropbox_access_key",
|
||||
"fieldtype": "Password",
|
||||
"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": "Dropbox Access Key",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "dropbox_access_key",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 1,
|
||||
"label": "Dropbox Access Key",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "dropbox_access_secret",
|
||||
"fieldtype": "Password",
|
||||
"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": "Dropbox Access 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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "dropbox_access_secret",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 1,
|
||||
"label": "Dropbox Access Secret",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "dropbox_access_token",
|
||||
"fieldtype": "Password",
|
||||
"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": "Dropbox Access Token",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldname": "dropbox_access_token",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 1,
|
||||
"label": "Dropbox Access Token"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 1,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-01-03 05:44:40.520943",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Dropbox Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"in_create": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2019-08-22 16:26:44.468391",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Dropbox Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 1,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
],
|
||||
"read_only": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
|
|
@ -3,22 +3,25 @@
|
|||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import dropbox
|
||||
import json
|
||||
import frappe
|
||||
import os
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
import dropbox, json
|
||||
from frappe.integrations.offsite_backup_utils import get_latest_backup_file, send_email, validate_file_size
|
||||
from frappe.integrations.utils import make_post_request
|
||||
from frappe.utils import (cint, get_request_site_address,
|
||||
get_files_path, get_backups_path, get_url, encode)
|
||||
from frappe.utils.backups import new_backup
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from six.moves.urllib.parse import urlparse, parse_qs
|
||||
from frappe.integrations.utils import make_post_request
|
||||
from rq.timeouts import JobTimeoutException
|
||||
from frappe.utils import (cint, split_emails, get_request_site_address,
|
||||
get_files_path, get_backups_path, get_url, encode)
|
||||
from six import text_type
|
||||
|
||||
ignore_list = [".DS_Store"]
|
||||
|
||||
|
||||
class DropboxSettings(Document):
|
||||
def onload(self):
|
||||
if not self.app_access_key and frappe.conf.dropbox_access_key:
|
||||
|
|
@ -48,10 +51,12 @@ def take_backup_to_dropbox(retry_count=0, upload_db_backup=True):
|
|||
did_not_upload, error_log = [], []
|
||||
try:
|
||||
if cint(frappe.db.get_value("Dropbox Settings", None, "enabled")):
|
||||
validate_file_size()
|
||||
|
||||
did_not_upload, error_log = backup_to_dropbox(upload_db_backup)
|
||||
if did_not_upload: raise Exception
|
||||
|
||||
send_email(True, "Dropbox")
|
||||
send_email(True, "Dropbox", "Dropbox Settings", "send_notifications_to")
|
||||
except JobTimeoutException:
|
||||
if retry_count < 2:
|
||||
args = {
|
||||
|
|
@ -66,34 +71,8 @@ def take_backup_to_dropbox(retry_count=0, upload_db_backup=True):
|
|||
else:
|
||||
file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
|
||||
error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
|
||||
frappe.errprint(error_message)
|
||||
send_email(False, "Dropbox", error_message)
|
||||
|
||||
def send_email(success, service_name, error_status=None):
|
||||
if success:
|
||||
if frappe.db.get_value("Dropbox Settings", None, "send_email_for_successful_backup") == '0':
|
||||
return
|
||||
|
||||
subject = "Backup Upload Successful"
|
||||
message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
|
||||
that your backup was successfully uploaded to your %s account. So relax!</p>
|
||||
""" % service_name
|
||||
|
||||
else:
|
||||
subject = "[Warning] Backup Upload Failed"
|
||||
message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s
|
||||
failed.</p>
|
||||
<p>Error message: <br>
|
||||
<pre><code>%s</code></pre>
|
||||
</p>
|
||||
<p>Please contact your system manager for more information.</p>
|
||||
""" % (service_name, error_status)
|
||||
|
||||
if not frappe.db:
|
||||
frappe.connect()
|
||||
|
||||
recipients = split_emails(frappe.db.get_value("Dropbox Settings", None, "send_notifications_to"))
|
||||
frappe.sendmail(recipients=recipients, subject=subject, message=message)
|
||||
send_email(False, "Dropbox", "Dropbox Settings", "send_notifications_to", error_message)
|
||||
|
||||
def backup_to_dropbox(upload_db_backup=True):
|
||||
if not frappe.db:
|
||||
|
|
@ -114,8 +93,12 @@ def backup_to_dropbox(upload_db_backup=True):
|
|||
dropbox_client = dropbox.Dropbox(dropbox_settings['access_token'])
|
||||
|
||||
if upload_db_backup:
|
||||
backup = new_backup(ignore_files=True)
|
||||
filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
|
||||
if frappe.flags.create_new_backup:
|
||||
backup = new_backup(ignore_files=True)
|
||||
filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
|
||||
else:
|
||||
filename = get_latest_backup_file()
|
||||
|
||||
upload_file_to_dropbox(filename, "/database", dropbox_client)
|
||||
|
||||
# delete older databases
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestDropboxSettings(unittest.TestCase):
|
||||
pass
|
||||
|
|
@ -19,6 +19,7 @@ from apiclient.http import MediaFileUpload
|
|||
from frappe.utils import get_backups_path, get_bench_path
|
||||
from frappe.utils.backups import new_backup
|
||||
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url
|
||||
from frappe.integrations.offsite_backup_utils import get_latest_backup_file, send_email, validate_file_size
|
||||
|
||||
SCOPES = "https://www.googleapis.com/auth/drive"
|
||||
|
||||
|
|
@ -183,13 +184,16 @@ def upload_system_backup_to_google_drive():
|
|||
check_for_folder_in_google_drive()
|
||||
account.load_from_db()
|
||||
|
||||
progress(1, "Backing up Data.")
|
||||
backup = new_backup()
|
||||
|
||||
fileurl_backup = os.path.basename(backup.backup_path_db)
|
||||
fileurl_public_files = os.path.basename(backup.backup_path_files)
|
||||
fileurl_private_files = os.path.basename(backup.backup_path_private_files)
|
||||
validate_file_size()
|
||||
|
||||
if frappe.flags.create_new_backup:
|
||||
set_progress(1, "Backing up Data.")
|
||||
backup = new_backup()
|
||||
fileurl_backup = os.path.basename(backup.backup_path_db)
|
||||
fileurl_public_files = os.path.basename(backup.backup_path_files)
|
||||
fileurl_private_files = os.path.basename(backup.backup_path_private_files)
|
||||
else:
|
||||
fileurl_backup, fileurl_public_files, fileurl_private_files = get_latest_backup_file(with_files=True)
|
||||
|
||||
for fileurl in [fileurl_backup, fileurl_public_files, fileurl_private_files]:
|
||||
file_metadata = {
|
||||
|
|
@ -203,15 +207,14 @@ def upload_system_backup_to_google_drive():
|
|||
frappe.throw(_("Google Drive - Could not locate locate - {0}").format(e))
|
||||
|
||||
try:
|
||||
progress(2, "Uploading backup to Google Drive.")
|
||||
set_progress(2, "Uploading backup to Google Drive.")
|
||||
google_drive.files().create(body=file_metadata, media_body=media, fields="id").execute()
|
||||
except HttpError as e:
|
||||
send_email(success=False, error=e)
|
||||
frappe.msgprint(_("Google Drive - Could not upload backup - Error {0}").format(e))
|
||||
send_email(False, "Google Drive", "Google Drive", "email", error_status=e)
|
||||
|
||||
progress(3, "Uploading successful.")
|
||||
set_progress(3, "Uploading successful.")
|
||||
frappe.db.set_value("Google Drive", None, "last_backup_on", frappe.utils.now_datetime())
|
||||
send_email(success=True)
|
||||
send_email(True, "Google Drive", "Google Drive", "email")
|
||||
return _("Google Drive Backup Successful.")
|
||||
|
||||
def daily_backup():
|
||||
|
|
@ -226,30 +229,5 @@ def get_absolute_path(filename):
|
|||
file_path = os.path.join(get_backups_path()[2:], filename)
|
||||
return "{0}/sites/{1}".format(get_bench_path(), file_path)
|
||||
|
||||
def progress(progress, message):
|
||||
def set_progress(progress, message):
|
||||
frappe.publish_realtime("upload_to_google_drive", dict(progress=progress, total=3, message=message), user=frappe.session.user)
|
||||
|
||||
def send_email(success, error=None):
|
||||
if success:
|
||||
if not frappe.db.get_single_value("Google Drive", "send_email_for_successful_backup"):
|
||||
return
|
||||
|
||||
subject = "Backup Upload Successful"
|
||||
message = """<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
|
||||
that your backup was successfully uploaded to Google Drive.</p>
|
||||
"""
|
||||
else:
|
||||
subject = "[Warning] Backup Upload Failed"
|
||||
message = """<h3>Backup Upload Failed</h3><p>Oops, your automated backup to Google Drive
|
||||
failed.</p>
|
||||
<p>Error message: <br>
|
||||
<pre><code>{0}</code></pre>
|
||||
</p>
|
||||
<p>Please contact your system manager for more information.</p>
|
||||
""".format(error)
|
||||
|
||||
frappe.sendmail(
|
||||
recipients=frappe.db.get_single_value("Google Drive", "email"),
|
||||
subject=subject,
|
||||
message=message
|
||||
)
|
||||
|
|
@ -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.<br> 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.<br> 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<br>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<br>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
|
||||
}
|
||||
|
|
@ -1,397 +1,110 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-09-04 20:57:20.129205",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"creation": "2017-09-04 20:57:20.129205",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"enabled",
|
||||
"notify_email",
|
||||
"send_email_for_successful_backup",
|
||||
"frequency",
|
||||
"access_key_id",
|
||||
"secret_access_key",
|
||||
"region",
|
||||
"endpoint_url",
|
||||
"bucket",
|
||||
"backup_limit"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "enabled",
|
||||
"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": "Enable Automatic Backup",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "0",
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Automatic Backup"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "notify_email",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Send Notifications To",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "notify_email",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Send Notifications To",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"description": "Note: By default emails for failed backups are sent.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "send_email_for_successful_backup",
|
||||
"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": "Send Email for Successful Backup",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "1",
|
||||
"description": "Note: By default emails for failed backups are sent.",
|
||||
"fieldname": "send_email_for_successful_backup",
|
||||
"fieldtype": "Check",
|
||||
"label": "Send Email for Successful Backup"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "frequency",
|
||||
"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": 0,
|
||||
"label": "Backup Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Daily\nWeekly\nMonthly\nNone",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "frequency",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Backup Frequency",
|
||||
"options": "Daily\nWeekly\nMonthly\nNone",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "access_key_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Access Key ID",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "access_key_id",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Access Key ID",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "secret_access_key",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Secret Access Key",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "secret_access_key",
|
||||
"fieldtype": "Password",
|
||||
"in_list_view": 1,
|
||||
"label": "Secret Access Key",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "us-east-1",
|
||||
"description": "See https://docs.aws.amazon.com/de_de/general/latest/gr/rande.html#s3_region for details.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "region",
|
||||
"fieldtype": "Select",
|
||||
"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": "Region",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "us-east-1\nus-east-2\nus-west-1\nus-west-2\nap-south-1\nap-southeast-1\nap-southeast-2\nap-northeast-1\nap-northeast-2\nap-northeast-3\nca-central-1\ncn-north-1\ncn-northwest-1\neu-central-1\neu-west-1\neu-west-2\neu-west-3\neu-north-1\nsa-east-1",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "us-east-1",
|
||||
"description": "See https://docs.aws.amazon.com/de_de/general/latest/gr/rande.html#s3_region for details.",
|
||||
"fieldname": "region",
|
||||
"fieldtype": "Select",
|
||||
"label": "Region",
|
||||
"options": "us-east-1\nus-east-2\nus-west-1\nus-west-2\nap-south-1\nap-southeast-1\nap-southeast-2\nap-northeast-1\nap-northeast-2\nap-northeast-3\nca-central-1\ncn-north-1\ncn-northwest-1\neu-central-1\neu-west-1\neu-west-2\neu-west-3\neu-north-1\nsa-east-1"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "endpoint_url",
|
||||
"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": "Endpoint URL",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "endpoint_url",
|
||||
"fieldtype": "Data",
|
||||
"label": "Endpoint URL"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "bucket",
|
||||
"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": "Bucket",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "bucket",
|
||||
"fieldtype": "Data",
|
||||
"label": "Bucket",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "backup_limit",
|
||||
"fieldtype": "Int",
|
||||
"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": "Backup Limit",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldname": "backup_limit",
|
||||
"fieldtype": "Int",
|
||||
"label": "Backup Limit",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_toolbar": 1,
|
||||
"idx": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2019-04-10 03:56:55.632017",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "S3 Backup Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2019-08-22 16:26:04.774571",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "S3 Backup Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
|
|
@ -8,12 +8,14 @@ import os.path
|
|||
import frappe
|
||||
import boto3
|
||||
from frappe import _
|
||||
from frappe.integrations.offsite_backup_utils import get_latest_backup_file, send_email, validate_file_size
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, split_emails
|
||||
from frappe.utils import cint
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from rq.timeouts import JobTimeoutException
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
class S3BackupSettings(Document):
|
||||
|
||||
def validate(self):
|
||||
|
|
@ -49,7 +51,7 @@ class S3BackupSettings(Document):
|
|||
|
||||
@frappe.whitelist()
|
||||
def take_backup():
|
||||
"Enqueue longjob for taking backup to s3"
|
||||
"""Enqueue longjob for taking backup to s3"""
|
||||
enqueue("frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_s3", queue='long', timeout=1500)
|
||||
frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour."))
|
||||
|
||||
|
|
@ -65,22 +67,21 @@ def take_backups_weekly():
|
|||
def take_backups_monthly():
|
||||
take_backups_if("Monthly")
|
||||
|
||||
|
||||
def take_backups_if(freq):
|
||||
if cint(frappe.db.get_value("S3 Backup Settings", None, "enabled")):
|
||||
if frappe.db.get_value("S3 Backup Settings", None, "frequency") == freq:
|
||||
take_backups_s3()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def take_backups_s3(retry_count=0):
|
||||
try:
|
||||
validate_file_size()
|
||||
backup_to_s3()
|
||||
send_email(True, "S3 Backup Settings")
|
||||
send_email(True, "Amazon S3", "S3 Backup Settings", "notify_email")
|
||||
except JobTimeoutException:
|
||||
if retry_count < 2:
|
||||
args = {
|
||||
"retry_count" :retry_count + 1
|
||||
"retry_count": retry_count + 1
|
||||
}
|
||||
enqueue("frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_s3",
|
||||
queue='long', timeout=1500, **args)
|
||||
|
|
@ -89,31 +90,10 @@ def take_backups_s3(retry_count=0):
|
|||
except Exception:
|
||||
notify()
|
||||
|
||||
|
||||
def notify():
|
||||
error_message = frappe.get_traceback()
|
||||
frappe.errprint(error_message)
|
||||
send_email(False, "S3 Backup Settings", error_message)
|
||||
|
||||
def send_email(success, service_name, error_status=None):
|
||||
if success:
|
||||
if frappe.db.get_value("S3 Backup Settings", None, "send_email_for_successful_backup") == '0':
|
||||
return
|
||||
|
||||
subject = "Backup Upload Successful"
|
||||
message = """<h3>Backup Uploaded Successfully! </h3><p>Hi there, this is just to inform you
|
||||
that your backup was successfully uploaded to your Amazon S3 bucket. So relax!</p> """
|
||||
|
||||
else:
|
||||
subject = "[Warning] Backup Upload Failed"
|
||||
message = """<h3>Backup Upload Failed! </h3><p>Oops, your automated backup to Amazon S3 failed.
|
||||
</p> <p>Error message: %s</p> <p>Please contact your system manager
|
||||
for more information.</p>""" % error_status
|
||||
|
||||
if not frappe.db:
|
||||
frappe.connect()
|
||||
|
||||
recipients = split_emails(frappe.db.get_value("S3 Backup Settings", None, "notify_email"))
|
||||
frappe.sendmail(recipients=recipients, subject=subject, message=message)
|
||||
send_email(False, 'Amazon S3', "S3 Backup Settings", "notify_email", error_message)
|
||||
|
||||
|
||||
def backup_to_s3():
|
||||
|
|
@ -130,11 +110,15 @@ def backup_to_s3():
|
|||
endpoint_url=doc.endpoint_url or 'https://s3.amazonaws.com'
|
||||
)
|
||||
|
||||
backup = new_backup(ignore_files=False, backup_path_db=None,
|
||||
if frappe.flags.create_new_backup:
|
||||
backup = new_backup(ignore_files=False, backup_path_db=None,
|
||||
backup_path_files=None, backup_path_private_files=None, force=True)
|
||||
db_filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
|
||||
files_filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_files))
|
||||
private_files = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_private_files))
|
||||
db_filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
|
||||
files_filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_files))
|
||||
private_files = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_private_files))
|
||||
else:
|
||||
db_filename, files_filename, private_files = get_latest_backup_file(with_files=True)
|
||||
|
||||
folder = os.path.basename(db_filename)[:15] + '/'
|
||||
# for adding datetime to folder name
|
||||
|
||||
|
|
@ -143,8 +127,8 @@ def backup_to_s3():
|
|||
upload_file_to_s3(files_filename, folder, conn, bucket)
|
||||
delete_old_backups(doc.backup_limit, bucket)
|
||||
|
||||
def upload_file_to_s3(filename, folder, conn, bucket):
|
||||
|
||||
def upload_file_to_s3(filename, folder, conn, bucket):
|
||||
destpath = os.path.join(folder, os.path.basename(filename))
|
||||
try:
|
||||
print("Uploading file:", filename)
|
||||
|
|
@ -156,7 +140,7 @@ def upload_file_to_s3(filename, folder, conn, bucket):
|
|||
|
||||
|
||||
def delete_old_backups(limit, bucket):
|
||||
all_backups = list()
|
||||
all_backups = []
|
||||
doc = frappe.get_single("S3 Backup Settings")
|
||||
backup_limit = int(limit)
|
||||
|
||||
|
|
|
|||
83
frappe/integrations/offsite_backup_utils.py
Normal file
83
frappe/integrations/offsite_backup_utils.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import glob
|
||||
import os
|
||||
from frappe.utils import split_emails, get_backups_path
|
||||
|
||||
|
||||
def send_email(success, service_name, doctype, email_field, error_status=None):
|
||||
recipients = get_recipients(service_name, email_field)
|
||||
if not recipients:
|
||||
frappe.log_error("No Email Recipient found for {0}".format(service_name),
|
||||
"{0}: Failed to send backup status email".format(service_name))
|
||||
return
|
||||
|
||||
if success:
|
||||
if not frappe.db.get_value(doctype, None, "send_email_for_successful_backup"):
|
||||
return
|
||||
|
||||
subject = "Backup Upload Successful"
|
||||
message = """
|
||||
<h3>Backup Uploaded Successfully!</h3>
|
||||
<p>Hi there, this is just to inform you that your backup was successfully uploaded to your {0} bucket. So relax!</p>""".format(service_name)
|
||||
|
||||
else:
|
||||
subject = "[Warning] Backup Upload Failed"
|
||||
message = """
|
||||
<h3>Backup Upload Failed!</h3>
|
||||
<p>Oops, your automated backup to {0} failed.</p>
|
||||
<p>Error message: {1}</p>
|
||||
<p>Please contact your system manager for more information.</p>""".format(service_name, error_status)
|
||||
|
||||
frappe.sendmail(recipients=recipients, subject=subject, message=message)
|
||||
|
||||
|
||||
def get_recipients(service_name, email_field):
|
||||
if not frappe.db:
|
||||
frappe.connect()
|
||||
|
||||
return split_emails(frappe.db.get_value(service_name, None, email_field))
|
||||
|
||||
|
||||
def get_latest_backup_file(with_files=False):
|
||||
|
||||
def get_latest(file_ext):
|
||||
file_list = glob.glob(os.path.join(get_backups_path(), file_ext))
|
||||
return max(file_list, key=os.path.getctime)
|
||||
|
||||
latest_file = get_latest('*.sql.gz')
|
||||
|
||||
if with_files:
|
||||
latest_public_file_bak = get_latest('*-files.tar')
|
||||
latest_private_file_bak = get_latest('*-private-files.tar')
|
||||
return latest_file, latest_public_file_bak, latest_private_file_bak
|
||||
|
||||
return latest_file
|
||||
|
||||
|
||||
def get_file_size(file_path, unit):
|
||||
if not unit:
|
||||
unit = 'MB'
|
||||
|
||||
file_size = os.path.getsize(file_path)
|
||||
|
||||
memory_size_unit_mapper = {'KB': 1, 'MB': 2, 'GB': 3, 'TB': 4}
|
||||
i = 0
|
||||
while i < memory_size_unit_mapper[unit]:
|
||||
file_size = file_size / 1000.0
|
||||
i += 1
|
||||
|
||||
return file_size
|
||||
|
||||
|
||||
def validate_file_size():
|
||||
frappe.flags.create_new_backup = True
|
||||
latest_file = get_latest_backup_file()
|
||||
file_size = get_file_size(latest_file, unit='GB')
|
||||
|
||||
if file_size > 1:
|
||||
frappe.flags.create_new_backup = False
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -271,3 +271,4 @@ execute:frappe.delete_doc_if_exists('DocType', 'GSuite Templates')
|
|||
execute:frappe.delete_doc_if_exists('DocType', 'GCalendar Account')
|
||||
execute:frappe.delete_doc_if_exists('DocType', 'GCalendar Settings')
|
||||
frappe.patches.v12_0.remove_parent_and_parenttype_from_print_formats
|
||||
execute:from frappe.desk.page.setup_wizard.install_fixtures import update_genders;update_genders()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.desk.page.setup_wizard.install_fixtures import update_genders_and_salutations
|
||||
from frappe.desk.page.setup_wizard.install_fixtures import update_genders, update_salutations
|
||||
|
||||
def execute():
|
||||
frappe.db.set_value("DocType", "Contact", "module", "Contacts")
|
||||
|
|
@ -11,4 +11,5 @@ def execute():
|
|||
frappe.reload_doc('contacts', 'doctype', 'gender')
|
||||
frappe.reload_doc('contacts', 'doctype', 'salutation')
|
||||
|
||||
update_genders_and_salutations()
|
||||
update_genders()
|
||||
update_salutations()
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(`
|
||||
<p>${__("Current status")}: ${state.bold()}</p>
|
||||
<p>${__("Document is only editable by users with role")}: ${document_editable_by}</p>
|
||||
<p>${__("Next actions")}: ${next_actions}</p>
|
||||
<p>${__("{0}: Other permission rules may also apply", [__('Note').bold()])}</p>
|
||||
`).css({padding: '15px'});
|
||||
|
||||
$(d.body).html("<p>"+__("Current status")+": " + state.bold() + "</p>"
|
||||
+ "<p>"+__("Document is only editable by users of role")+": "
|
||||
+ frappe.workflow.get_document_state(me.frm.doctype,
|
||||
state).allow_edit.bold() + "</p>"
|
||||
+ "<p>"+__("Next actions")+": "+ next_html +"</p>"
|
||||
+ (me.frm.doc.__islocal ? ("<div class='alert alert-info'>"
|
||||
+__("Workflow will start after saving.")+"</div>") : "")
|
||||
+ "<p class='help'>"+__("Note: Other permission rules may also apply")+"</p>"
|
||||
).css({padding: '15px'});
|
||||
d.show();
|
||||
});
|
||||
}, true);
|
||||
|
|
@ -115,7 +113,7 @@ frappe.ui.form.States = Class.extend({
|
|||
} else {
|
||||
this.setup_btn(added);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 `<li class="group-by-field list-link">
|
||||
|
|
|
|||
|
|
@ -125,11 +125,14 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
return this.set_value(key, val);
|
||||
},
|
||||
set_values: function(dict) {
|
||||
let promises = [];
|
||||
for(var key in dict) {
|
||||
if(this.fields_dict[key]) {
|
||||
this.set_value(key, dict[key]);
|
||||
promises.push(this.set_value(key, dict[key]));
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
clear: function() {
|
||||
for(var key in this.fields_dict) {
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ $.extend(frappe.ui.toolbar, {
|
|||
fullwidth = !fullwidth;
|
||||
localStorage.container_fullwidth = fullwidth;
|
||||
frappe.ui.toolbar.set_fullwidth_if_enabled();
|
||||
$(document.body).trigger('toggleFullWidth');
|
||||
},
|
||||
set_fullwidth_if_enabled() {
|
||||
let fullwidth = JSON.parse(localStorage.container_fullwidth || 'false');
|
||||
|
|
|
|||
|
|
@ -122,9 +122,11 @@ Object.assign(frappe.utils, {
|
|||
</a></p>');
|
||||
return content.html();
|
||||
},
|
||||
scroll_to: function(element, animate, additional_offset) {
|
||||
scroll_to: function(element, animate, additional_offset, element_to_be_scrolled) {
|
||||
element_to_be_scrolled = element_to_be_scrolled || $("html, body");
|
||||
|
||||
var y = 0;
|
||||
if(element && typeof element==='number') {
|
||||
if (element && typeof element==="number") {
|
||||
y = element;
|
||||
} else if(element) {
|
||||
var header_offset = $(".navbar").height() + $(".page-head").height();
|
||||
|
|
@ -136,14 +138,14 @@ Object.assign(frappe.utils, {
|
|||
}
|
||||
|
||||
// already there
|
||||
if(y==$('html, body').scrollTop()) {
|
||||
if (y == element_to_be_scrolled.scrollTop()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (animate!==false) {
|
||||
$("html, body").animate({ scrollTop: y });
|
||||
if (animate !== false) {
|
||||
element_to_be_scrolled.animate({ scrollTop: y });
|
||||
} else {
|
||||
$(window).scrollTop(y);
|
||||
element_to_be_scrolled.scrollTop(y);
|
||||
}
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
export default class Desktop {
|
||||
constructor({ wrapper }) {
|
||||
this.wrapper = wrapper;
|
||||
window.desk = this;
|
||||
this.pages = {};
|
||||
this.sidebar_items = {};
|
||||
this.sidebar_categories = [
|
||||
|
|
@ -45,12 +44,12 @@ export default class Desktop {
|
|||
this.desktop_settings = response.message;
|
||||
} else {
|
||||
frappe.throw({
|
||||
title: "Couldn't Load Desk",
|
||||
title: __("Couldn't Load Desk"),
|
||||
message:
|
||||
"Something went wrong while loading Desk. <b>Please relaod the page</b>. If the problem persists, contact the Administrator",
|
||||
__("Something went wrong while loading Desk. <b>Please relaod the page</b>. If the problem persists, contact the Administrator"),
|
||||
indicator: "red",
|
||||
primary_action: {
|
||||
label: "Reload",
|
||||
label: __("Reload"),
|
||||
action: () => location.reload()
|
||||
}
|
||||
});
|
||||
|
|
@ -64,7 +63,7 @@ export default class Desktop {
|
|||
item.name}" class="sidebar-item ${
|
||||
item.selected ? "selected" : ""
|
||||
}">
|
||||
<span>${item.name}</span>
|
||||
<span>${item.label || item.name}</span>
|
||||
</div>`);
|
||||
};
|
||||
|
||||
|
|
@ -79,8 +78,10 @@ export default class Desktop {
|
|||
};
|
||||
|
||||
const make_category_title = name => {
|
||||
// DO NOT REMOVE: Comment to load translation
|
||||
// __("Modules") __("Domains") __("Places") __("Administration")
|
||||
let $title = $(
|
||||
`<div class="sidebar-group-title h6 uppercase">${name}</div>`
|
||||
`<div class="sidebar-group-title h6 uppercase">${__(name)}</div>`
|
||||
);
|
||||
$title.appendTo(this.sidebar);
|
||||
};
|
||||
|
|
@ -106,8 +107,6 @@ export default class Desktop {
|
|||
}
|
||||
this.current_page = page;
|
||||
localStorage.current_desk_page = page;
|
||||
frappe.set_route("workspace", page);
|
||||
|
||||
this.pages[page] ? this.pages[page].show() : this.make_page(page);
|
||||
}
|
||||
|
||||
|
|
@ -131,20 +130,20 @@ export default class Desktop {
|
|||
this.pages[page] = $page;
|
||||
return $page;
|
||||
}
|
||||
|
||||
setup_events() {}
|
||||
}
|
||||
|
||||
class DesktopPage {
|
||||
constructor({ container, page_name }) {
|
||||
frappe.desk_page = this;
|
||||
this.container = container;
|
||||
this.page_name = page_name;
|
||||
this.sections = {};
|
||||
this.allow_customization = false;
|
||||
this.make();
|
||||
this.reload();
|
||||
}
|
||||
|
||||
show() {
|
||||
frappe.desk_page = this;
|
||||
this.page.show();
|
||||
}
|
||||
|
||||
|
|
@ -152,8 +151,34 @@ class DesktopPage {
|
|||
this.page.hide();
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.in_customize_mode = false;
|
||||
this.page && this.page.remove();
|
||||
this.make();
|
||||
this.setup_events();
|
||||
}
|
||||
|
||||
make_customization_link() {
|
||||
this.customize_link = $(`<div class="small customize-options" style="cursor: pointer;">${__('Customize Workspace')}</div>`);
|
||||
this.customize_link.appendTo(this.page);
|
||||
this.customize_link.on('click', () => {
|
||||
this.customize();
|
||||
});
|
||||
|
||||
this.save_or_discard_link = $(`<div class="small customize-options small-bounce">
|
||||
<span class="save-customization">${__('Save')}</span> / <span class="discard-customization">${__('Discard')}</span>
|
||||
</div>`).hide();
|
||||
|
||||
this.save_or_discard_link.appendTo(this.page);
|
||||
this.save_or_discard_link.find(".save-customization").on("click", () => this.save_customization());
|
||||
this.save_or_discard_link.find(".discard-customization").on("click", () => this.reload());
|
||||
this.page.addClass('allow-customization');
|
||||
}
|
||||
|
||||
make() {
|
||||
this.make_page();
|
||||
this.page = $(`<div class="desk-page" data-page-name=${this.page_name}></div>`);
|
||||
this.page.appendTo(this.container);
|
||||
|
||||
this.get_data().then(res => {
|
||||
this.data = res.message;
|
||||
// this.make_onboarding();
|
||||
|
|
@ -163,28 +188,32 @@ class DesktopPage {
|
|||
return;
|
||||
}
|
||||
|
||||
this.allow_customization = this.data.allow_customization || false;
|
||||
|
||||
let create_shortcuts_and_cards = () => {
|
||||
this.data.shortcuts.items.length && this.make_shortcuts();
|
||||
this.data.cards.items.length && this.make_cards();
|
||||
};
|
||||
|
||||
if (!this.sections["onboarding"] && this.data.charts.items.length) {
|
||||
this.make_charts().then(() => {
|
||||
create_shortcuts_and_cards();
|
||||
});
|
||||
} else {
|
||||
create_shortcuts_and_cards();
|
||||
}
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
make_page() {
|
||||
this.page = $(
|
||||
`<div class="desk-page" data-page-name=${this.page_name}></div>`
|
||||
);
|
||||
this.page.appendTo(this.container);
|
||||
refresh() {
|
||||
this.page.empty();
|
||||
this.allow_customization = this.data.allow_customization || false;
|
||||
this.allow_customization && this.make_customization_link();
|
||||
|
||||
let create_shortcuts_and_cards = () => {
|
||||
this.data.shortcuts.items.length && this.make_shortcuts();
|
||||
this.data.cards.items.length && this.make_cards();
|
||||
|
||||
if (this.allow_customization) {
|
||||
// Move the widget group up to align with labels if customization is allowed
|
||||
$('.desk-page .widget-group:visible:first').css('margin-top', '-25px');
|
||||
}
|
||||
};
|
||||
|
||||
if (!this.sections["onboarding"] && this.data.charts.items.length) {
|
||||
this.make_charts().then(() => {
|
||||
create_shortcuts_and_cards();
|
||||
});
|
||||
} else {
|
||||
create_shortcuts_and_cards();
|
||||
}
|
||||
}
|
||||
|
||||
get_data() {
|
||||
|
|
@ -193,40 +222,50 @@ class DesktopPage {
|
|||
});
|
||||
}
|
||||
|
||||
make_onboarding() {
|
||||
this.sections["onboarding"] = new frappe.widget.WidgetGroup({
|
||||
title: `Getting Started`,
|
||||
container: this.page,
|
||||
type: "onboarding",
|
||||
columns: 1,
|
||||
widgets: [
|
||||
{
|
||||
label: "Unlock Great Customer Experience",
|
||||
subtitle: "Just a few steps, and you’re good to go.",
|
||||
steps: [
|
||||
{
|
||||
label: "Configure Lead Sources",
|
||||
completed: true
|
||||
},
|
||||
{
|
||||
label: "Add Your Leads",
|
||||
completed: false
|
||||
},
|
||||
{
|
||||
label: "Create Your First Opportunity",
|
||||
completed: false
|
||||
},
|
||||
{
|
||||
label: "Onboard your Sales Team",
|
||||
completed: false
|
||||
},
|
||||
{
|
||||
label: "Assign Territories",
|
||||
completed: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
setup_events() {
|
||||
$(document.body).on('toggleFullWidth', () => this.refresh());
|
||||
}
|
||||
|
||||
customize() {
|
||||
if (this.in_customize_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It may be possible the chart area is hidden since it has no widgets
|
||||
// So the margin-top: -25px would be applied to the shortcut group
|
||||
// We need to remove this as the chart group will be visible during customization
|
||||
$('.desk-page .widget-group:visible:first').css('margin-top', '0px');
|
||||
|
||||
this.customize_link.hide();
|
||||
this.save_or_discard_link.show();
|
||||
|
||||
Object.keys(this.sections).forEach(section => {
|
||||
this.sections[section].customize();
|
||||
});
|
||||
this.in_customize_mode = true;
|
||||
|
||||
// Move the widget group up to align with labels if customization is allowed
|
||||
$('.desk-page .widget-group:visible:first').css('margin-top', '-25px');
|
||||
}
|
||||
|
||||
save_customization() {
|
||||
const config = {};
|
||||
|
||||
if (this.sections.charts) config.charts = this.sections.charts.get_widget_config();
|
||||
if (this.sections.shortcuts) config.shortcuts = this.sections.shortcuts.get_widget_config();
|
||||
if (this.sections.cards) config.cards = this.sections.cards.get_widget_config();
|
||||
|
||||
frappe.call('frappe.desk.desktop.save_customization', {
|
||||
page: this.page_name,
|
||||
config: config
|
||||
}).then(res => {
|
||||
if (res.message) {
|
||||
frappe.msgprint({ message: __("Customizations Saved Successfully"), title: __("Success")});
|
||||
this.reload();
|
||||
} else {
|
||||
frappe.throw({message: __("Something went wrong while saving customizations"), title: __("Failed")});
|
||||
this.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -240,11 +279,18 @@ class DesktopPage {
|
|||
}
|
||||
|
||||
this.sections["charts"] = new frappe.widget.WidgetGroup({
|
||||
title: this.data.charts.label || `${this.page_name} Dashboard`,
|
||||
title: this.data.charts.label || __('{} Dashboard', [__(this.page_name)]),
|
||||
container: this.page,
|
||||
type: "chart",
|
||||
columns: 1,
|
||||
allow_sorting: false,
|
||||
options: {
|
||||
allow_sorting: this.allow_customization && !frappe.is_mobile(),
|
||||
allow_create: this.allow_customization,
|
||||
allow_delete: this.allow_customization,
|
||||
allow_hiding: false,
|
||||
allow_edit: true,
|
||||
max_widget_count: 2,
|
||||
},
|
||||
widgets: this.data.charts.items
|
||||
});
|
||||
});
|
||||
|
|
@ -252,22 +298,34 @@ class DesktopPage {
|
|||
|
||||
make_shortcuts() {
|
||||
this.sections["shortcuts"] = new frappe.widget.WidgetGroup({
|
||||
title: this.data.shortcuts.label || `Your Shortcuts`,
|
||||
title: this.data.shortcuts.label || __(`Your Shortcuts`),
|
||||
container: this.page,
|
||||
type: "bookmark",
|
||||
type: "shortcut",
|
||||
columns: 3,
|
||||
allow_sorting: this.allow_customization && frappe.is_mobile(),
|
||||
options: {
|
||||
allow_sorting: this.allow_customization && !frappe.is_mobile(),
|
||||
allow_create: this.allow_customization,
|
||||
allow_delete: this.allow_customization,
|
||||
allow_hiding: false,
|
||||
allow_edit: true,
|
||||
},
|
||||
widgets: this.data.shortcuts.items
|
||||
});
|
||||
}
|
||||
|
||||
make_cards() {
|
||||
let cards = new frappe.widget.WidgetGroup({
|
||||
title: this.data.cards.label || `Reports & Masters`,
|
||||
title: this.data.cards.label || __(`Reports & Masters`),
|
||||
container: this.page,
|
||||
type: "links",
|
||||
columns: 3,
|
||||
allow_sorting: this.allow_customization && frappe.is_mobile(),
|
||||
options: {
|
||||
allow_sorting: this.allow_customization && !frappe.is_mobile(),
|
||||
allow_create: false,
|
||||
allow_delete: false,
|
||||
allow_hiding: this.allow_customization,
|
||||
allow_edit: false,
|
||||
},
|
||||
widgets: this.data.cards.items
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import get_dialog_constructor from './widget_dialog.js';
|
||||
|
||||
export default class Widget {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
|
|
@ -8,22 +10,71 @@ export default class Widget {
|
|||
this.set_title();
|
||||
this.set_actions();
|
||||
this.set_body();
|
||||
this.setup_events();
|
||||
}
|
||||
|
||||
customize() {
|
||||
get_config() {
|
||||
return {
|
||||
name: this.name,
|
||||
label: this.label
|
||||
};
|
||||
}
|
||||
|
||||
customize(options) {
|
||||
this.in_customize_mode = true;
|
||||
this.action_area.empty();
|
||||
|
||||
options.allow_delete &&
|
||||
this.add_custom_button(
|
||||
'<i class="fa fa-trash" aria-hidden="true"></i>',
|
||||
() => this.delete()
|
||||
);
|
||||
|
||||
options.allow_sorting &&
|
||||
this.add_custom_button(
|
||||
'<i class="fa fa-arrows" aria-hidden="true"></i>',
|
||||
null,
|
||||
"drag-handle"
|
||||
);
|
||||
|
||||
if (options.allow_hiding) {
|
||||
if (this.hidden) {
|
||||
this.widget.removeClass("hidden");
|
||||
this.body.css("opacity", 0.5);
|
||||
this.title_field.css("opacity", 0.5);
|
||||
this.footer.css("opacity", 0.5);
|
||||
}
|
||||
const classname = this.hidden ? 'fa fa-eye' : 'fa fa-eye-slash';
|
||||
this.add_custom_button(
|
||||
`<i class="${classname}" aria-hidden="true"></i>`,
|
||||
() => this.hide_or_show(),
|
||||
"show-or-hide-button"
|
||||
);
|
||||
|
||||
this.show_or_hide_button = this.action_area.find(
|
||||
".show-or-hide-button"
|
||||
);
|
||||
}
|
||||
|
||||
options.allow_edit &&
|
||||
this.add_custom_button(
|
||||
'<i class="fa fa-pencil" aria-hidden="true"></i>',
|
||||
() => this.edit()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
make() {
|
||||
this.make_widget();
|
||||
this.widget.appendTo(this.container);
|
||||
this.setup_events();
|
||||
}
|
||||
|
||||
make_widget() {
|
||||
this.widget = $(`<div class="widget">
|
||||
this.widget = $(`<div class="widget ${
|
||||
this.hidden ? "hidden" : ""
|
||||
}" data-widget-name=${this.name ? this.name : ''}>
|
||||
<div class="widget-head">
|
||||
<div class="widget-title"></div>
|
||||
<div class="widget-title ellipsis"></div>
|
||||
<div class="widget-control"></div>
|
||||
</div>
|
||||
<div class="widget-body">
|
||||
|
|
@ -37,13 +88,74 @@ export default class Widget {
|
|||
this.action_area = this.widget.find(".widget-control");
|
||||
this.head = this.widget.find(".widget-head");
|
||||
this.footer = this.widget.find(".widget-footer");
|
||||
this.set_title();
|
||||
this.set_actions();
|
||||
this.set_body();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
set_title() {
|
||||
this.title_field[0].innerHTML = this.label || this.name;
|
||||
this.title_field[0].innerHTML = this.label;
|
||||
}
|
||||
|
||||
add_custom_button(html, action, class_name = "") {
|
||||
let button = $(
|
||||
`<button class="btn btn-default btn-xs ${class_name}">${html}</button>`
|
||||
);
|
||||
button.click(event => {
|
||||
event.stopPropagation();
|
||||
action && action();
|
||||
});
|
||||
button.appendTo(this.action_area);
|
||||
}
|
||||
|
||||
delete() {
|
||||
this.widget.addClass("zoomOutDelete");
|
||||
// wait for animation
|
||||
setTimeout(() => {
|
||||
this.widget.remove();
|
||||
this.options.on_delete && this.options.on_delete(this.name);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
edit() {
|
||||
const dialog_class = get_dialog_constructor(this.widget_type);
|
||||
|
||||
this.edit_dialog = new dialog_class({
|
||||
label: this.label,
|
||||
type: this.widget_type,
|
||||
values: this.get_config(),
|
||||
primary_action: (data) => {
|
||||
Object.assign(this, data);
|
||||
data.name = this.name;
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
primary_action_label: __("Save")
|
||||
});
|
||||
|
||||
this.edit_dialog.make();
|
||||
}
|
||||
|
||||
hide_or_show() {
|
||||
if (!this.hidden) {
|
||||
this.body.css("opacity", 0.5);
|
||||
this.title_field.css("opacity", 0.5);
|
||||
this.footer.css("opacity", 0.5);
|
||||
this.hidden = true;
|
||||
} else {
|
||||
this.body.css("opacity", 1);
|
||||
this.title_field.css("opacity", 1);
|
||||
this.footer.css("opacity", 1);
|
||||
this.hidden = false;
|
||||
}
|
||||
this.show_or_hide_button.empty();
|
||||
|
||||
const classname = this.hidden ? 'fa fa-eye' : 'fa fa-eye-slash';
|
||||
$(`<i class="${classname}" aria-hidden="true"></i>`).appendTo(
|
||||
this.show_or_hide_button
|
||||
);
|
||||
}
|
||||
|
||||
setup_events() {
|
||||
//
|
||||
}
|
||||
|
||||
set_actions() {
|
||||
|
|
@ -53,8 +165,4 @@ export default class Widget {
|
|||
set_body() {
|
||||
//
|
||||
}
|
||||
|
||||
setup_events() {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,19 @@ export default class ChartWidget extends Widget {
|
|||
this.height = 240;
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.make_chart();
|
||||
get_config() {
|
||||
return {
|
||||
name: this.name,
|
||||
chart_name: this.chart_name,
|
||||
label: this.label,
|
||||
};
|
||||
}
|
||||
|
||||
customize() {
|
||||
this.setup_customize_actions();
|
||||
refresh() {
|
||||
delete this.dashboard_chart;
|
||||
this.set_title();
|
||||
this.set_body();
|
||||
this.make_chart();
|
||||
}
|
||||
|
||||
set_body() {
|
||||
|
|
@ -67,28 +74,22 @@ export default class ChartWidget extends Widget {
|
|||
}
|
||||
this.setup_container();
|
||||
this.prepare_chart_object();
|
||||
this.action_area.empty();
|
||||
this.prepare_chart_actions();
|
||||
this.setup_filter_button();
|
||||
if (!this.in_customize_mode) {
|
||||
this.action_area.empty();
|
||||
this.prepare_chart_actions();
|
||||
this.setup_filter_button();
|
||||
|
||||
if (
|
||||
this.chart_doc.timeseries &&
|
||||
this.chart_doc.chart_type !== "Custom"
|
||||
) {
|
||||
this.render_time_series_filters();
|
||||
if (
|
||||
this.chart_doc.timeseries &&
|
||||
this.chart_doc.chart_type !== "Custom"
|
||||
) {
|
||||
this.render_time_series_filters();
|
||||
}
|
||||
}
|
||||
|
||||
this.fetch_and_update_chart();
|
||||
});
|
||||
}
|
||||
|
||||
setup_customize_actions() {
|
||||
this.action_area.empty();
|
||||
const buttons = $(`<button type="button" class="btn btn-xs btn-secondary btn-default selected">Resize</button>
|
||||
<button class="btn btn-secondary btn-light btn-danger btn-xs"><i class="fa fa-trash" aria-hidden="true"></i></button>`);
|
||||
buttons.appendTo(this.action_area);
|
||||
}
|
||||
|
||||
render_time_series_filters() {
|
||||
let filters = [
|
||||
{
|
||||
|
|
@ -428,9 +429,7 @@ export default class ChartWidget extends Widget {
|
|||
}
|
||||
|
||||
fetch(filters, refresh = false, args) {
|
||||
let method = this.settings
|
||||
? this.settings.method
|
||||
: "frappe.desk.doctype.dashboard_chart.dashboard_chart.get";
|
||||
let method = this.settings.method;
|
||||
|
||||
if (this.chart_doc.chart_type == "Report") {
|
||||
args = {
|
||||
|
|
@ -558,6 +557,9 @@ export default class ChartWidget extends Widget {
|
|||
};
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
this.settings = {
|
||||
method: "frappe.desk.doctype.dashboard_chart.dashboard_chart.get"
|
||||
};
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,8 +6,13 @@ export default class LinksWidget extends Widget {
|
|||
super(opts);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
//
|
||||
get_config() {
|
||||
return {
|
||||
name: this.name,
|
||||
links: JSON.stringify(this.links),
|
||||
label: this.label,
|
||||
hidden: this.hidden,
|
||||
};
|
||||
}
|
||||
|
||||
set_body() {
|
||||
|
|
@ -75,21 +80,22 @@ export default class LinksWidget extends Widget {
|
|||
const popover = link.find(".module-link-popover");
|
||||
|
||||
link_label.mouseover(() => {
|
||||
if (this.in_customize_mode) return;
|
||||
popover.show();
|
||||
});
|
||||
link_label.mouseout(() => popover.hide());
|
||||
} else {
|
||||
if (link_label.hasClass("help-video-link")) {
|
||||
link_label.click(event => {
|
||||
link_label.click(event => {
|
||||
if (this.in_customize_mode) return;
|
||||
|
||||
if (link_label.hasClass("help-video-link")) {
|
||||
let yt_id = event.target.dataset.youtubeid;
|
||||
frappe.help.show_video(yt_id);
|
||||
});
|
||||
} else {
|
||||
link_label.click(event => {
|
||||
} else {
|
||||
let route = event.target.dataset.route;
|
||||
frappe.set_route(route);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
52
frappe/public/js/frappe/widgets/new_widget.js
Normal file
52
frappe/public/js/frappe/widgets/new_widget.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import get_dialog_constructor from "./widget_dialog.js";
|
||||
|
||||
export default class NewWidget {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
this.make();
|
||||
}
|
||||
|
||||
customize() {
|
||||
return;
|
||||
}
|
||||
|
||||
make() {
|
||||
this.make_widget();
|
||||
this.widget.appendTo(this.container);
|
||||
this.setup_events();
|
||||
}
|
||||
|
||||
get_title() {
|
||||
// DO NOT REMOVE: Comment to load translation
|
||||
// __("New Chart") __("New Shortcut")
|
||||
return __(`New ${frappe.utils.to_title_case(this.type)}`);
|
||||
}
|
||||
|
||||
make_widget() {
|
||||
this.widget = $(`<div class="widget new-widget">
|
||||
+ ${this.get_title()}
|
||||
</div>`);
|
||||
this.body = this.widget;
|
||||
}
|
||||
|
||||
setup_events() {
|
||||
this.widget.on("click", () => this.open_dialog());
|
||||
}
|
||||
|
||||
open_dialog() {
|
||||
const dialog_class = get_dialog_constructor(this.type);
|
||||
|
||||
this.dialog = new dialog_class({
|
||||
label: this.label,
|
||||
type: this.type,
|
||||
values: false,
|
||||
primary_action: this.on_create,
|
||||
});
|
||||
|
||||
this.dialog.make();
|
||||
}
|
||||
|
||||
delete() {
|
||||
this.widget.remove();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ import Widget from "./base_widget.js";
|
|||
export default class OnboardingWidget extends Widget {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
window.onb = this;
|
||||
}
|
||||
|
||||
refresh() { }
|
||||
|
|
|
|||
|
|
@ -1,48 +1,62 @@
|
|||
import Widget from "./base_widget.js";
|
||||
import { generate_route } from "./utils";
|
||||
// import { get_luminosity, shadeColor } from "./utils";
|
||||
|
||||
String.prototype.format = function () {
|
||||
var i = 0, args = arguments;
|
||||
return this.replace(/{}/g, function () {
|
||||
return typeof args[i] != 'undefined' ? args[i++] : '';
|
||||
});
|
||||
};
|
||||
|
||||
export default class ShortcutWidget extends Widget {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
//
|
||||
get_config() {
|
||||
return {
|
||||
name: this.name,
|
||||
icon: this.icon,
|
||||
label: this.label,
|
||||
format: this.format,
|
||||
link_to: this.link_to,
|
||||
color: this.color,
|
||||
restrict_to_domain: this.restrict_to_domain,
|
||||
stats_filter: this.stats_filter,
|
||||
type: this.type,
|
||||
};
|
||||
}
|
||||
|
||||
setup_events() {
|
||||
this.widget.click(() => {
|
||||
let route = generate_route(this)
|
||||
frappe.set_route(route)
|
||||
})
|
||||
if (this.in_customize_mode) return;
|
||||
|
||||
let route = generate_route({
|
||||
route: this.route,
|
||||
name: this.link_to,
|
||||
type: this.type,
|
||||
is_query_report: this.is_query_report,
|
||||
doctype: this.ref_doctype
|
||||
});
|
||||
|
||||
frappe.set_route(route);
|
||||
});
|
||||
}
|
||||
|
||||
set_actions() {
|
||||
this.widget.addClass('shortcut-widget-box');
|
||||
const get_filter = new Function(`return ${this.stats_filter}`)
|
||||
if (this.in_customize_mode) return;
|
||||
|
||||
this.widget.addClass("shortcut-widget-box");
|
||||
const get_filter = new Function(`return ${this.stats_filter}`);
|
||||
if (this.type == "DocType" && this.stats_filter) {
|
||||
frappe.db.count(this.link_to, {
|
||||
filters: get_filter()
|
||||
}).then(count => this.set_count(count))
|
||||
frappe.db
|
||||
.count(this.link_to, {
|
||||
filters: get_filter(),
|
||||
})
|
||||
.then((count) => this.set_count(count));
|
||||
}
|
||||
}
|
||||
|
||||
set_title() {
|
||||
if (this.icon) {
|
||||
this.title_field[0].innerHTML = `<div>
|
||||
<i class="${this.icon}" style="color: rgb(141, 153, 166); font-size: 18px; margin-right: 6px;"></i>
|
||||
<i class="${this.icon}" style=""></i>
|
||||
${this.label || this.name}
|
||||
</div>`
|
||||
}
|
||||
else {
|
||||
</div>`;
|
||||
} else {
|
||||
super.set_title();
|
||||
}
|
||||
}
|
||||
|
|
@ -50,19 +64,22 @@ export default class ShortcutWidget extends Widget {
|
|||
set_count(count) {
|
||||
const get_label = () => {
|
||||
if (this.format) {
|
||||
return this.format.format(count);
|
||||
return this.format.replace(/{}/g, count);
|
||||
}
|
||||
return count
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
this.action_area.empty();
|
||||
const label = get_label();
|
||||
const buttons = $(`<div class="small pill">${label}</div>`);
|
||||
if(this.color) {
|
||||
buttons.css('background-color', this.color);
|
||||
buttons.css('color', frappe.ui.color.get_contrast_color(this.color))
|
||||
if (this.color) {
|
||||
buttons.css("background-color", this.color);
|
||||
buttons.css(
|
||||
"color",
|
||||
frappe.ui.color.get_contrast_color(this.color)
|
||||
);
|
||||
}
|
||||
|
||||
buttons.appendTo(this.action_area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
266
frappe/public/js/frappe/widgets/widget_dialog.js
Normal file
266
frappe/public/js/frappe/widgets/widget_dialog.js
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
class WidgetDialog {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
this.editing = Boolean(this.values && Object.keys(this.values).length);
|
||||
}
|
||||
|
||||
make() {
|
||||
this.make_dialog();
|
||||
this.setup_dialog_events();
|
||||
this.dialog.show();
|
||||
|
||||
this.editing && this.set_default_values();
|
||||
}
|
||||
|
||||
make_dialog() {
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: this.get_title(),
|
||||
fields: this.get_fields(),
|
||||
primary_action: (data) => {
|
||||
data = this.process_data(data);
|
||||
|
||||
if (!this.editing) {
|
||||
data.name = `${this.type}-${this.label}-${frappe.utils.get_random(20)}`;
|
||||
}
|
||||
|
||||
this.dialog.hide();
|
||||
this.primary_action(data);
|
||||
},
|
||||
primary_action_label: this.primary_action_label || __("Add"),
|
||||
});
|
||||
}
|
||||
|
||||
get_title() {
|
||||
// DO NOT REMOVE: Comment to load translation
|
||||
// __("New Chart") __("New Shortcut") __("Edit Chart") __("Edit Shortcut")
|
||||
|
||||
let action = this.editing ? "Edit" : "Add";
|
||||
return __(`${action} ${frappe.utils.to_title_case(this.type)}`);
|
||||
}
|
||||
|
||||
get_fields() {
|
||||
//
|
||||
}
|
||||
|
||||
set_default_values() {
|
||||
return this.dialog.set_values(this.values);
|
||||
}
|
||||
|
||||
process_data(data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
setup_dialog_events() {
|
||||
//
|
||||
}
|
||||
|
||||
hide_field(fieldname) {
|
||||
this.dialog.set_df_property(fieldname, "hidden", true);
|
||||
}
|
||||
|
||||
show_field(fieldname) {
|
||||
this.dialog.set_df_property(fieldname, "hidden", false);
|
||||
}
|
||||
}
|
||||
|
||||
class ChartDialog extends WidgetDialog {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
}
|
||||
|
||||
get_fields() {
|
||||
return [
|
||||
{
|
||||
fieldtype: "Link",
|
||||
fieldname: "chart_name",
|
||||
label: "Chart Name",
|
||||
options: "Dashboard Chart",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "label",
|
||||
label: "Label",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
process_data(data) {
|
||||
data.label = data.label ? data.label : data.chart_name;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class ShortcutDialog extends WidgetDialog {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
}
|
||||
|
||||
hide_filters() {
|
||||
this.hide_field("count_section_break");
|
||||
this.hide_field("filters_section_break");
|
||||
}
|
||||
|
||||
show_filters() {
|
||||
this.show_field("count_section_break");
|
||||
this.show_field("filters_section_break");
|
||||
}
|
||||
|
||||
get_fields() {
|
||||
return [
|
||||
{
|
||||
fieldtype: "Select",
|
||||
fieldname: "type",
|
||||
label: "Type",
|
||||
reqd: 1,
|
||||
options: "DocType\nReport\nPage",
|
||||
onchange: () => {
|
||||
if (this.dialog.get_value("type") == "DocType") {
|
||||
this.dialog.fields_dict.link_to.get_query = () => {
|
||||
return { filters: { istable: false } };
|
||||
};
|
||||
} else {
|
||||
this.dialog.fields_dict.link_to.get_query = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "label",
|
||||
label: "Label",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
fieldname: "column_break_4",
|
||||
},
|
||||
{
|
||||
fieldtype: "Dynamic Link",
|
||||
fieldname: "link_to",
|
||||
label: "Link To",
|
||||
reqd: 1,
|
||||
options: "type",
|
||||
onchange: () => {
|
||||
if (this.dialog.get_value("type") == "DocType") {
|
||||
let doctype = this.dialog.get_value("link_to");
|
||||
|
||||
doctype &&
|
||||
frappe.db
|
||||
.get_value("DocType", doctype, "issingle")
|
||||
.then((res) => {
|
||||
if (res.message && res.message.issingle) {
|
||||
this.hide_filters();
|
||||
} else {
|
||||
this.setup_filter(doctype);
|
||||
this.show_filters();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.hide_filters();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
fieldname: "filters_section_break",
|
||||
label: "Count Filter",
|
||||
hidden: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "HTML",
|
||||
fieldname: "filter_area_loading",
|
||||
},
|
||||
{
|
||||
fieldtype: "HTML",
|
||||
fieldname: "filter_area",
|
||||
hidden: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
fieldname: "count_section_break",
|
||||
label: "Count Customizations",
|
||||
hidden: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Color",
|
||||
fieldname: "color",
|
||||
label: "Color",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
fieldname: "column_break_3",
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "format",
|
||||
label: "Format",
|
||||
description: "For Example: {} Open",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
set_default_values() {
|
||||
super.set_default_values().then(() => {
|
||||
this.dialog.fields_dict.link_to.df.onchange();
|
||||
});
|
||||
}
|
||||
|
||||
process_data(data) {
|
||||
let stats_filter = {};
|
||||
|
||||
if (this.dialog.get_value("type") == "DocType" && this.filter_group) {
|
||||
let filters = this.filter_group.get_filters();
|
||||
filters.forEach((arr) => {
|
||||
stats_filter[arr[1]] = [arr[2], arr[3]];
|
||||
});
|
||||
|
||||
data.stats_filter = JSON.stringify(stats_filter);
|
||||
}
|
||||
|
||||
data.label = data.label
|
||||
? data.label
|
||||
: frappe.model.unscrub(data.link_to);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
setup_filter(doctype) {
|
||||
if (this.filter_group) {
|
||||
this.filter_group.wrapper.empty();
|
||||
delete this.filter_group;
|
||||
}
|
||||
|
||||
let $loading = this.dialog.get_field("filter_area_loading").$wrapper;
|
||||
$(`<span class="text-muted">Loading Filters...</span>`).appendTo($loading);
|
||||
|
||||
this.filters = [];
|
||||
|
||||
if (this.values && this.values.stats_filter) {
|
||||
const filters_json = JSON.parse(this.values.stats_filter);
|
||||
this.filters = Object.keys(filters_json).map((filter) => {
|
||||
let val = filters_json[filter];
|
||||
return [this.values.link_to, filter, val[0], val[1], false];
|
||||
});
|
||||
}
|
||||
|
||||
this.filter_group = new frappe.ui.FilterGroup({
|
||||
parent: this.dialog.get_field("filter_area").$wrapper,
|
||||
doctype: doctype,
|
||||
on_change: () => {},
|
||||
});
|
||||
|
||||
frappe.model.with_doctype(doctype, () => {
|
||||
this.filter_group.add_filters_to_filter_group(this.filters);
|
||||
this.hide_field("filter_area_loading");
|
||||
this.show_field("filter_area");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default function get_dialog_constructor(type) {
|
||||
const widget_map = {
|
||||
chart: ChartDialog,
|
||||
shortcut: ShortcutDialog,
|
||||
};
|
||||
|
||||
return widget_map[type] || WidgetDialog;
|
||||
}
|
||||
|
|
@ -3,46 +3,31 @@ import BaseWidget from "../widgets/base_widget";
|
|||
import ShortcutWidget from "../widgets/shortcut_widget";
|
||||
import LinksWidget from "../widgets/links_widget";
|
||||
import OnboardingWidget from "../widgets/onboarding_widget";
|
||||
import NewWidget from "../widgets/new_widget";
|
||||
|
||||
frappe.provide('frappe.widget')
|
||||
frappe.provide("frappe.widget");
|
||||
|
||||
const widget_factory = {
|
||||
chart: ChartWidget,
|
||||
base: BaseWidget,
|
||||
bookmark: ShortcutWidget,
|
||||
shortcut: ShortcutWidget,
|
||||
links: LinksWidget,
|
||||
onboarding: OnboardingWidget
|
||||
onboarding: OnboardingWidget,
|
||||
};
|
||||
|
||||
export default class WidgetGroup {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
// opts = {
|
||||
// title: "CRM Dashboard",
|
||||
// container: $(''),
|
||||
// widgets: [
|
||||
// {type: "dashboard", width: "Full", options: {}}.
|
||||
// {type: "dashboard", width: "Full", options: {}}
|
||||
// ],
|
||||
// allow_delete: true,
|
||||
// allow_create: true,
|
||||
// allow_rearrange: true,
|
||||
// hide_edit_option: false,
|
||||
// collapsible: false
|
||||
// }
|
||||
window.wid_area = this;
|
||||
this.widgets_list = [];
|
||||
this.widgets_dict = {};
|
||||
this.widget_order = [];
|
||||
this.make();
|
||||
}
|
||||
|
||||
make() {
|
||||
this.make_container();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.title && this.set_title(this.title);
|
||||
this.title && this.set_title();
|
||||
this.widgets && this.make_widgets();
|
||||
this.allow_sorting && this.setup_sortable();
|
||||
}
|
||||
|
||||
make_container() {
|
||||
|
|
@ -58,22 +43,94 @@ export default class WidgetGroup {
|
|||
this.title_area = widget_area.find(".widget-group-title");
|
||||
this.control_area = widget_area.find(".widget-group-control");
|
||||
this.body = widget_area.find(".widget-group-body");
|
||||
!this.widgets.length && this.widget_area.hide();
|
||||
widget_area.appendTo(this.container);
|
||||
}
|
||||
|
||||
set_title(title) {
|
||||
set_title() {
|
||||
this.title_area[0].innerText = this.title;
|
||||
}
|
||||
|
||||
make_widgets() {
|
||||
this.body.empty()
|
||||
this.body.empty();
|
||||
this.widgets.forEach((widget) => {
|
||||
this.add_widget(widget);
|
||||
});
|
||||
}
|
||||
|
||||
add_widget(widget) {
|
||||
const widget_class = widget_factory[this.type];
|
||||
|
||||
this.widgets.forEach(widget => {
|
||||
new widget_class({
|
||||
...widget,
|
||||
container: this.body
|
||||
})
|
||||
let widget_object = new widget_class({
|
||||
...widget,
|
||||
widget_type: this.type,
|
||||
container: this.body,
|
||||
options: {
|
||||
...this.options,
|
||||
on_delete: (name) => this.on_delete(name),
|
||||
},
|
||||
});
|
||||
|
||||
this.widgets_list.push(widget_object);
|
||||
this.widgets_dict[widget.name] = widget_object;
|
||||
|
||||
return widget_object;
|
||||
}
|
||||
|
||||
customize() {
|
||||
this.widget_area.show();
|
||||
this.widgets_list.forEach((wid) => {
|
||||
wid.customize(this.options);
|
||||
});
|
||||
|
||||
this.options.allow_create && this.setup_new_widget();
|
||||
this.options.allow_sorting && this.setup_sortable();
|
||||
}
|
||||
|
||||
setup_new_widget() {
|
||||
const max = this.options
|
||||
? this.options.max_widget_count || Number.POSITIVE_INFINITY
|
||||
: Number.POSITIVE_INFINITY;
|
||||
|
||||
if (this.widgets_list.length < max) {
|
||||
this.new_widget = new NewWidget({
|
||||
container: this.body,
|
||||
type: this.type,
|
||||
on_create: (config) => {
|
||||
// Remove new widget
|
||||
this.new_widget.delete();
|
||||
delete this.new_widget;
|
||||
|
||||
config.in_customize_mode = 1;
|
||||
|
||||
// Add new widget and customize it
|
||||
let wid = this.add_widget(config);
|
||||
wid.customize(this.options);
|
||||
|
||||
// Put back the new widget if required
|
||||
if (this.widgets_list.length < max) {
|
||||
this.setup_new_widget();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
on_delete(name) {
|
||||
this.widgets_list = this.widgets_list.filter((wid) => name != wid.name);
|
||||
delete this.widgets_dict[name];
|
||||
this.update_widget_order();
|
||||
|
||||
if (!this.new_widget) this.setup_new_widget();
|
||||
}
|
||||
|
||||
update_widget_order() {
|
||||
this.widget_order = [];
|
||||
this.body.children().each((index, element) => {
|
||||
let name = element.dataset.widgetName;
|
||||
if (name) {
|
||||
this.widget_order.push(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -81,13 +138,26 @@ export default class WidgetGroup {
|
|||
const container = this.body[0];
|
||||
this.sortable = new Sortable(container, {
|
||||
animation: 150,
|
||||
onEnd: () => {
|
||||
console.log("Sorting")
|
||||
},
|
||||
// onChoose: (evt) => this.sortable_config.on_choose(evt, container),
|
||||
// onStart: (evt) => this.sortable_config.on_start(evt, container)
|
||||
handle: ".drag-handle",
|
||||
onEnd: () => this.update_widget_order(),
|
||||
});
|
||||
}
|
||||
|
||||
get_widget_config() {
|
||||
this.update_widget_order();
|
||||
let prepared_dict = {};
|
||||
|
||||
this.widgets_list.forEach((wid) => {
|
||||
let config = wid.get_config();
|
||||
let name = config.docname ? config.docname : config.name;
|
||||
prepared_dict[name] = config;
|
||||
});
|
||||
|
||||
return {
|
||||
order: this.widget_order,
|
||||
widgets: prepared_dict,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
frappe.widget.WidgetGroup = WidgetGroup;
|
||||
frappe.widget.WidgetGroup = WidgetGroup;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,24 @@
|
|||
position: relative;
|
||||
min-height: 1px;
|
||||
padding-right: 15px;
|
||||
|
||||
.desk-page.allow-customization {
|
||||
.customize-options {
|
||||
text-align: right;
|
||||
margin-top: 7px;
|
||||
color: @text-muted;
|
||||
z-index: 99;
|
||||
|
||||
.save-customization {
|
||||
cursor: pointer;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.discard-customization {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
|
@ -90,6 +108,9 @@
|
|||
|
||||
.widget-group {
|
||||
margin-bottom: 25px;
|
||||
// -webkit-animation-name: slideInUp;
|
||||
// animation-name: slideInUp;
|
||||
// animation-duration: 0.4s;
|
||||
|
||||
.widget-group-head {
|
||||
display: flex;
|
||||
|
|
@ -201,6 +222,17 @@
|
|||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: all-scroll;
|
||||
cursor: -webkit-grabbing;
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-date-field {
|
||||
.clearfix,
|
||||
.help-box {
|
||||
|
|
@ -220,6 +252,16 @@
|
|||
border-color: @disabled-background
|
||||
}
|
||||
|
||||
&.new-widget {
|
||||
min-height: 65px;
|
||||
background-color: @disabled-background;
|
||||
color: @text-muted;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// Overrides for each widgets
|
||||
&.dashboard-widget-box {
|
||||
padding: 10px 15px !important;
|
||||
|
|
@ -300,6 +342,14 @@
|
|||
.widget-head {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.widget-title {
|
||||
i {
|
||||
color: @text-muted;
|
||||
font-size: 18px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -357,23 +407,153 @@
|
|||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.pill-green {
|
||||
background: #71b92c;
|
||||
// color: #000;
|
||||
@-webkit-keyframes smallBounce {
|
||||
from,
|
||||
20%,
|
||||
53%,
|
||||
80%,
|
||||
to {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
40%,
|
||||
43% {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
-webkit-transform: translate3d(0, -12px, 0);
|
||||
transform: translate3d(0, -12px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
-webkit-transform: translate3d(0, -6px, 0);
|
||||
transform: translate3d(0, -6px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0, -4px, 0);
|
||||
transform: translate3d(0, -4px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.pill-red {
|
||||
background: @red;
|
||||
@keyframes smallBounce {
|
||||
from,
|
||||
20%,
|
||||
53%,
|
||||
80%,
|
||||
to {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
40%,
|
||||
43% {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
-webkit-transform: translate3d(0, -12px, 0);
|
||||
transform: translate3d(0, -12px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
-webkit-transform: translate3d(0, -6px, 0);
|
||||
transform: translate3d(0, -6px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0, -4px, 0);
|
||||
transform: translate3d(0, -4px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.pill-blue {
|
||||
background: @blue;
|
||||
.small-bounce {
|
||||
-webkit-animation-name: smallBounce;
|
||||
animation-name: smallBounce;
|
||||
-webkit-transform-origin: center bottom;
|
||||
transform-origin: center bottom;
|
||||
animation-duration: 1s;
|
||||
}
|
||||
|
||||
.pill-yellow {
|
||||
background: @yellow;
|
||||
@-webkit-keyframes slideInUp {
|
||||
from {
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.pill-orange {
|
||||
background: @orange;
|
||||
@keyframes slideInUp {
|
||||
from {
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.slide-in-up {
|
||||
-webkit-animation-name: slideInUp;
|
||||
animation-name: slideInUp;
|
||||
animation-duration: 1s;
|
||||
}
|
||||
|
||||
|
||||
@-webkit-keyframes pulse {
|
||||
from {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: scale3d(1.05, 1.05, 1.05);
|
||||
transform: scale3d(1.05, 1.05, 1.05);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
from {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: scale3d(1.05, 1.05, 1.05);
|
||||
transform: scale3d(1.05, 1.05, 1.05);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.zoomOutDelete {
|
||||
// -webkit-animation-name: zoomOut;
|
||||
// animation-name: zoomOut;
|
||||
// animation-duration: 1s;
|
||||
transition: opacity 0.2s, visibility 0.2s, transform 0.2s;
|
||||
transform: scale3d(0.5, 0.5, 0.5);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
@ -262,6 +262,11 @@
|
|||
border-bottom: 1px solid @border-color;
|
||||
}
|
||||
|
||||
.grid-form-body {
|
||||
max-height: 75vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.grid-header-toolbar {
|
||||
display: flow-root;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
padding-bottom: 5px;
|
||||
max-width: 330px;
|
||||
min-width: 200px;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
.preview-field {
|
||||
padding-bottom: 10px;
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@
|
|||
<a href="{{ link }}" rel="nofollow" class="btn btn-primary btn-sm primary-action" style="padding: 8px 20px;">{{ _("Confirm Request") }}</a>
|
||||
</p>
|
||||
<p style="font-size: 85%;">
|
||||
{{_("You can also copy-paste this ")}} <a href="{{ link }}">{{_("Verification Link")}}</a>{{_(" to your browser")}}
|
||||
{% set verification_link = '<a href="{{ link }}">{{ _("Verification Link") }}</a>' %}
|
||||
{{_("You can also copy-paste this {0} to your browser").format(verification_link) }}
|
||||
</p>
|
||||
|
|
@ -4,9 +4,10 @@
|
|||
<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
|
||||
{%- set parents = parents[-3:] %}
|
||||
{% for parent in parents %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ url_prefix }}{{ parent.route | abs_url }}" itemprop="url">
|
||||
{{ parent.title or parent.label or parent.name or "" }}
|
||||
<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="breadcrumb-item">
|
||||
<a itemprop="item" href="{{ url_prefix }}{{ parent.route | abs_url }}" itemprop="url">
|
||||
<span itemprop="name">{{ parent.title or parent.label or parent.name or "" }}</span>
|
||||
<meta itemprop="position" content="{{ loop.index }}" />
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -137,3 +137,29 @@ p {
|
|||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.invalid-login {
|
||||
-webkit-animation: wiggle 0.5s linear;
|
||||
}
|
||||
|
||||
@-webkit-keyframes wiggle {
|
||||
8%,
|
||||
41% {
|
||||
-webkit-transform: translateX(-10px);
|
||||
}
|
||||
25%,
|
||||
58% {
|
||||
-webkit-transform: translateX(10px);
|
||||
}
|
||||
75% {
|
||||
-webkit-transform: translateX(-5px);
|
||||
}
|
||||
92% {
|
||||
-webkit-transform: translateX(5px);
|
||||
}
|
||||
0%,
|
||||
100% {
|
||||
-webkit-transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,14 @@ login.set_indicator = function(message, color) {
|
|||
.removeClass().addClass('indicator').addClass(color).text(message)
|
||||
}
|
||||
|
||||
login.set_invalid = function(message) {
|
||||
$(".login-content.page-card").addClass('invalid-login');
|
||||
setTimeout(() => {
|
||||
$(".login-content.page-card").removeClass('invalid-login');
|
||||
}, 500)
|
||||
login.set_indicator(message, 'red');
|
||||
}
|
||||
|
||||
login.login_handlers = (function() {
|
||||
var get_error_handler = function(default_message) {
|
||||
return function(xhr, data) {
|
||||
|
|
@ -161,7 +169,7 @@ login.login_handlers = (function() {
|
|||
}
|
||||
|
||||
if(message===default_message) {
|
||||
login.set_indicator(message, 'red');
|
||||
login.set_invalid(message);
|
||||
} else {
|
||||
login.reset_sections(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ class TestDocument(unittest.TestCase):
|
|||
|
||||
# css attributes
|
||||
xss = '<div style="something: doesn\'t work; color: red;">Test</div>'
|
||||
escaped_xss = '<div style="color: red;">Test</div>'
|
||||
escaped_xss = '<div style="">Test</div>'
|
||||
d.subject += xss
|
||||
d.save()
|
||||
d.reload()
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ def get_datetime(datetime_str=None):
|
|||
elif isinstance(datetime_str, datetime.date):
|
||||
return datetime.datetime.combine(datetime_str, datetime.time())
|
||||
|
||||
# dateutil parser does not agree with dates like 0001-01-01
|
||||
if not datetime_str or (datetime_str or "").startswith("0001-01-01"):
|
||||
# dateutil parser does not agree with dates like "0001-01-01" or "0000-00-00"
|
||||
if not datetime_str or (datetime_str or "").startswith(("0001-01-01", "0000-00-00")):
|
||||
return None
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,26 +1,29 @@
|
|||
{
|
||||
"cards": [
|
||||
{
|
||||
"icon": "fa fa-cog",
|
||||
"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": "Setup"
|
||||
"hidden": 0,
|
||||
"label": "Setup",
|
||||
"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]"
|
||||
},
|
||||
{
|
||||
"links": "[\n {\n \"description\": \"Single Post (article).\",\n \"label\": \"Blog Post\",\n \"name\": \"Blog Post\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"A user who posts blogs.\",\n \"label\": \"Blogger\",\n \"name\": \"Blogger\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Categorize blog posts.\",\n \"label\": \"Blog Category\",\n \"name\": \"Blog Category\",\n \"type\": \"doctype\"\n }\n]",
|
||||
"title": "Blog"
|
||||
"hidden": 0,
|
||||
"label": "Blog",
|
||||
"links": "[\n {\n \"description\": \"Single Post (article).\",\n \"label\": \"Blog Post\",\n \"name\": \"Blog Post\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"A user who posts blogs.\",\n \"label\": \"Blogger\",\n \"name\": \"Blogger\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Categorize blog posts.\",\n \"label\": \"Blog Category\",\n \"name\": \"Blog Category\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"icon": "fa fa-star",
|
||||
"links": "[\n {\n \"description\": \"Content web page.\",\n \"label\": \"Web Page\",\n \"name\": \"Web Page\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"User editable form on Website.\",\n \"label\": \"Web Form\",\n \"name\": \"Web Form\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Website Sidebar\",\n \"name\": \"Website Sidebar\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Embed image slideshows in website pages.\",\n \"label\": \"Website Slideshow\",\n \"name\": \"Website Slideshow\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add meta tags to your web pages\",\n \"label\": \"Website Route Meta\",\n \"name\": \"Website Route Meta\",\n \"type\": \"doctype\"\n }\n]",
|
||||
"title": "Web Site"
|
||||
"hidden": 0,
|
||||
"label": "Web Site",
|
||||
"links": "[\n {\n \"description\": \"Content web page.\",\n \"label\": \"Web Page\",\n \"name\": \"Web Page\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"User editable form on Website.\",\n \"label\": \"Web Form\",\n \"name\": \"Web Form\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Website Sidebar\",\n \"name\": \"Website Sidebar\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Embed image slideshows in website pages.\",\n \"label\": \"Website Slideshow\",\n \"name\": \"Website Slideshow\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add meta tags to your web pages\",\n \"label\": \"Website Route Meta\",\n \"name\": \"Website Route Meta\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"links": "[\n {\n \"label\": \"Portal Settings\",\n \"name\": \"Portal Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
|
||||
"title": "Portal"
|
||||
"hidden": 0,
|
||||
"label": "Portal",
|
||||
"links": "[\n {\n \"label\": \"Portal Settings\",\n \"name\": \"Portal Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"links": "[\n {\n \"label\": \"Help Category\",\n \"name\": \"Help Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Help Article\",\n \"name\": \"Help Article\",\n \"type\": \"doctype\"\n }\n]",
|
||||
"title": "Knowledge Base"
|
||||
"hidden": 0,
|
||||
"label": "Knowledge Base",
|
||||
"links": "[\n {\n \"label\": \"Help Category\",\n \"name\": \"Help Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Help Article\",\n \"name\": \"Help Article\",\n \"type\": \"doctype\"\n }\n]"
|
||||
}
|
||||
],
|
||||
"category": "Modules",
|
||||
|
|
@ -34,7 +37,7 @@
|
|||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Website",
|
||||
"modified": "2020-03-12 16:30:43.092622",
|
||||
"modified": "2020-04-01 11:24:40.726934",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Website",
|
||||
|
|
@ -45,30 +48,30 @@
|
|||
{
|
||||
"color": "",
|
||||
"format": "{} Published",
|
||||
"is_query_report": 0,
|
||||
"label": "Blog Post",
|
||||
"link_to": "Blog Post",
|
||||
"stats_filter": "{\"published\":\"1\"}",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"format": "{} Active",
|
||||
"is_query_report": 0,
|
||||
"label": "Blogger",
|
||||
"link_to": "Blogger",
|
||||
"stats_filter": "{\"disabled\": 0}",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"is_query_report": 0,
|
||||
"label": "Web Page",
|
||||
"link_to": "Web Page",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"is_query_report": 0,
|
||||
"label": "Web Form",
|
||||
"link_to": "Web Form",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"is_query_report": 0,
|
||||
"label": "Website Settings",
|
||||
"link_to": "Website Settings",
|
||||
"type": "DocType"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,559 +1,142 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2013-02-21 20:12:42",
|
||||
"custom": 0,
|
||||
"description": "Settings for Contact Us Page",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 0,
|
||||
"actions": [],
|
||||
"creation": "2013-02-21 20:12:42",
|
||||
"description": "Settings for Contact Us Page",
|
||||
"doctype": "DocType",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"introduction_section",
|
||||
"forward_to_email",
|
||||
"heading",
|
||||
"introduction",
|
||||
"query_options",
|
||||
"address",
|
||||
"address_title",
|
||||
"address_line1",
|
||||
"address_line2",
|
||||
"city",
|
||||
"state",
|
||||
"pincode",
|
||||
"country",
|
||||
"column_break_14",
|
||||
"phone",
|
||||
"email_id",
|
||||
"skype"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "introduction_section",
|
||||
"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": "Introduction",
|
||||
"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
|
||||
},
|
||||
"fieldname": "introduction_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Introduction"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Send enquiries to this email address",
|
||||
"fieldname": "forward_to_email",
|
||||
"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": "Forward To Email Address",
|
||||
"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
|
||||
},
|
||||
"description": "Send enquiries to this email address",
|
||||
"fieldname": "forward_to_email",
|
||||
"fieldtype": "Data",
|
||||
"label": "Forward To Email Address",
|
||||
"options": "Email"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Default: \"Contact Us\"",
|
||||
"fieldname": "heading",
|
||||
"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": "Heading",
|
||||
"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
|
||||
},
|
||||
"description": "Default: \"Contact Us\"",
|
||||
"fieldname": "heading",
|
||||
"fieldtype": "Data",
|
||||
"label": "Heading"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Introductory information for the Contact Us Page",
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Text Editor",
|
||||
"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": "Introduction",
|
||||
"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
|
||||
},
|
||||
"description": "Introductory information for the Contact Us Page",
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Introduction"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Contact options, like \"Sales Query, Support Query\" etc each on a new line or separated by commas.",
|
||||
"fieldname": "query_options",
|
||||
"fieldtype": "Small 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": "Query Options",
|
||||
"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
|
||||
},
|
||||
"description": "Contact options, like \"Sales Query, Support Query\" etc each on a new line or separated by commas.",
|
||||
"fieldname": "query_options",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Query Options"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address",
|
||||
"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": "Address",
|
||||
"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
|
||||
},
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Address"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address_title",
|
||||
"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": "Address Title",
|
||||
"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
|
||||
},
|
||||
"bold": 1,
|
||||
"fieldname": "address_title",
|
||||
"fieldtype": "Data",
|
||||
"label": "Address Title"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address_line1",
|
||||
"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": "Address Line 1",
|
||||
"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
|
||||
},
|
||||
"fieldname": "address_line1",
|
||||
"fieldtype": "Data",
|
||||
"label": "Address Line 1"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address_line2",
|
||||
"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": "Address Line 2",
|
||||
"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
|
||||
},
|
||||
"fieldname": "address_line2",
|
||||
"fieldtype": "Data",
|
||||
"label": "Address Line 2"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "city",
|
||||
"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": "City",
|
||||
"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
|
||||
},
|
||||
"fieldname": "city",
|
||||
"fieldtype": "Data",
|
||||
"label": "City"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "state",
|
||||
"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": "State",
|
||||
"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
|
||||
},
|
||||
"fieldname": "state",
|
||||
"fieldtype": "Data",
|
||||
"label": "State"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "pincode",
|
||||
"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": "Pincode",
|
||||
"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
|
||||
},
|
||||
"fieldname": "pincode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Pincode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "country",
|
||||
"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": "Country",
|
||||
"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
|
||||
},
|
||||
"fieldname": "country",
|
||||
"fieldtype": "Data",
|
||||
"label": "Country"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_14",
|
||||
"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
|
||||
},
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "phone",
|
||||
"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": "Phone",
|
||||
"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
|
||||
},
|
||||
"fieldname": "phone",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone",
|
||||
"options": "Phone"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "email_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": "Email Id",
|
||||
"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
|
||||
},
|
||||
"fieldname": "email_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Email Id",
|
||||
"options": "Email"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "skype",
|
||||
"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": "Skype",
|
||||
"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
|
||||
"fieldname": "skype",
|
||||
"fieldtype": "Data",
|
||||
"label": "Skype"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-cog",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-04 21:41:55.580325",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Contact Us Settings",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2020-04-06 19:17:46.083764",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Contact Us Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Website Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "Website Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
Babel==2.6.0
|
||||
beautifulsoup4==4.8.2
|
||||
bleach-whitelist==0.0.10
|
||||
bleach==3.1.2
|
||||
bleach==3.1.4
|
||||
boto3==1.10.18
|
||||
braintree==3.57.1
|
||||
chardet==3.0.4
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue