From 05347eac9b8b116a3f844e21ba282180b6a4fa90 Mon Sep 17 00:00:00 2001 From: Mohammad Alhashash Date: Mon, 6 May 2013 22:04:20 +0200 Subject: [PATCH 001/423] Fixing bugs 1177076 and 1177063: Add module name in context view reference Add group stock.group_production_lot for Traceability section in view_move_form bzr revid: alhashash@centrivision.com-20130506200420-ph86vjd3d208ttly --- addons/stock/stock_view.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 83362ab5d6f..5878a578868 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -776,7 +776,7 @@ - + @@ -911,7 +911,7 @@ - +
@@ -1038,7 +1038,7 @@ - +
@@ -1256,7 +1256,7 @@ + groups="stock.group_tracking_lot,stock.group_production_lot">
- -
-
-

Get Statistics On Your Purchases

-
-

-Get accurate statistics on the performance of your suppliers through flexible reporting: delivery delays, negotiated discount on prices, quantities purchased, etc. Integrate purchases with the analytic accounting to analyse your contracts profitability. -

-
-
- -
-
-
diff --git a/addons/purchase/static/description/purchase_dashboard.png b/addons/purchase/static/description/purchase_dashboard.png deleted file mode 100644 index 0939edea591abb5f5eead391e30c49418cb125b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77350 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 z 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 Ef)NYmW&i*H From 64a187d894c5492399878e3ac4ac9761a651900d Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Wed, 29 Jan 2014 18:26:15 +0530 Subject: [PATCH 024/423] [remove]procurement and stock:remove procurement and stock dashboard bzr revid: sunilsharma.sharma07@gmail.com-20140129125615-96m0pzvmdfi0m0yz --- addons/procurement/__openerp__.py | 1 - .../board_mrp_procurement_view.xml | 24 ------- addons/stock/__openerp__.py | 5 +- addons/stock/board_warehouse_view.xml | 67 ------------------- 4 files changed, 2 insertions(+), 95 deletions(-) delete mode 100644 addons/procurement/board_mrp_procurement_view.xml delete mode 100644 addons/stock/board_warehouse_view.xml diff --git a/addons/procurement/__openerp__.py b/addons/procurement/__openerp__.py index 48569fa76c4..d18d2b862df 100644 --- a/addons/procurement/__openerp__.py +++ b/addons/procurement/__openerp__.py @@ -55,7 +55,6 @@ depending on the product's configuration. 'procurement_workflow.xml', 'process/procurement_process.xml', 'company_view.xml', - 'board_mrp_procurement_view.xml', ], 'demo': ['stock_orderpoint.xml','procurement_demo.xml'], 'test': ['test/procurement.yml'], diff --git a/addons/procurement/board_mrp_procurement_view.xml b/addons/procurement/board_mrp_procurement_view.xml deleted file mode 100644 index bb1b5e62d82..00000000000 --- a/addons/procurement/board_mrp_procurement_view.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Procurement Exceptions - ir.actions.act_window - procurement.order - form - tree,form - [('state','=','exception')] - - - - board.mrp.procurement.form - board.board - - - - - - - - - diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index dd2a996f6dd..1d3aa096b73 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -28,8 +28,8 @@ Manage multi-warehouses, multi- and structured stock locations ============================================================== -The warehouse and inventory management is based on a hierarchical location structure, from warehouses to storage bins. -The double entry inventory system allows you to manage customers, suppliers as well as manufacturing inventories. +The warehouse and inventory management is based on a hierarchical location structure, from warehouses to storage bins. +The double entry inventory system allows you to manage customers, suppliers as well as manufacturing inventories. OpenERP has the capacity to manage lots and serial numbers ensuring compliance with the traceability requirements imposed by the majority of industries. @@ -86,7 +86,6 @@ Dashboard / Reports for Warehouse Management will include: 'partner_view.xml', 'report/report_stock_move_view.xml', 'report/report_stock_view.xml', - 'board_warehouse_view.xml', 'res_config_view.xml', ], 'test': [ diff --git a/addons/stock/board_warehouse_view.xml b/addons/stock/board_warehouse_view.xml deleted file mode 100644 index a1f327eab5d..00000000000 --- a/addons/stock/board_warehouse_view.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - report.stock.move.graph - report.stock.move - - - - - - - - - - - Incoming Products - report.stock.move - form - graph,tree - [('type','=','in'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(context_today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] - - {'search_default_in':1} - - - Outgoing Products - report.stock.move - form - graph,tree - [('type','=','out'),('day','<=', time.strftime('%Y-%m-%d')),('day','>',(context_today()-datetime.timedelta(days=15)).strftime('%Y-%m-%d'))] - - {'search_default_out':1} - - - board.warehouse.form - board.board - -
- - - - - - - - -
-
-
- - - Warehouse - board.board - form - form - - - - - -
-
From 9328ac99082109ef98628ecfff31f00be6db6ac7 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Wed, 29 Jan 2014 18:43:53 +0530 Subject: [PATCH 025/423] [imp]:remove sapece bzr revid: sunilsharma.sharma07@gmail.com-20140129131353-26259ntx22t8wd4z --- addons/stock/__openerp__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 1d3aa096b73..343de1bb4ec 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -28,8 +28,8 @@ Manage multi-warehouses, multi- and structured stock locations ============================================================== -The warehouse and inventory management is based on a hierarchical location structure, from warehouses to storage bins. -The double entry inventory system allows you to manage customers, suppliers as well as manufacturing inventories. +The warehouse and inventory management is based on a hierarchical location structure, from warehouses to storage bins. +The double entry inventory system allows you to manage customers, suppliers as well as manufacturing inventories. OpenERP has the capacity to manage lots and serial numbers ensuring compliance with the traceability requirements imposed by the majority of industries. From 9a30e69787486c74a4aef8144f278808a20eb799 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Wed, 29 Jan 2014 18:54:37 +0530 Subject: [PATCH 026/423] [remove]:stock:remove stock dashboard description and image bzr revid: sunilsharma.sharma07@gmail.com-20140129132437-7r4id6sohcab0z9v --- addons/stock/__openerp__.py | 2 +- addons/stock/static/description/index.html | 17 ----------------- .../static/description/stock_reporting.png | Bin 25497 -> 0 bytes 3 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 addons/stock/static/description/stock_reporting.png diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 343de1bb4ec..d2a1a77886a 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -53,7 +53,7 @@ Dashboard / Reports for Warehouse Management will include: * Moves Analysis """, 'website': 'http://www.openerp.com', - 'images': ['images/stock_forecast_report.png', 'images/delivery_orders.jpeg', 'images/inventory_analysis.jpeg','images/location.jpeg','images/moves_analysis.jpeg','images/physical_inventories.jpeg','images/warehouse_dashboard.jpeg'], + 'images': ['images/stock_forecast_report.png', 'images/delivery_orders.jpeg', 'images/inventory_analysis.jpeg','images/location.jpeg','images/moves_analysis.jpeg','images/physical_inventories.jpeg'], 'depends': ['product', 'account'], 'category': 'Warehouse Management', 'sequence': 16, diff --git a/addons/stock/static/description/index.html b/addons/stock/static/description/index.html index dd7fbe568f7..8b5b3245653 100644 --- a/addons/stock/static/description/index.html +++ b/addons/stock/static/description/index.html @@ -185,23 +185,6 @@ based on a hierarchical location structure.
-
-
-

Reporting and Dashboards

-

Analyse your warehouse efficiency to improve performance

-
-

-Get the insights you need to make smarter decisions. Design custom dashboards -to get a picture of your warehouse efficiency at a glance. Dig deeper with -real-time reports that anyone can create and share. -

-
-
- -
-
-
-
diff --git a/addons/stock/static/description/stock_reporting.png b/addons/stock/static/description/stock_reporting.png deleted file mode 100644 index 1ec54d18813e6d04ff6b7b46363e46f9caf627ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25497 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 From 685121bea3758ebd4c2d5ef413f7877f4a07bd49 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Wed, 29 Jan 2014 19:01:15 +0530 Subject: [PATCH 027/423] [rem]:sale and crm :remove image bzr revid: sunilsharma.sharma07@gmail.com-20140129133115-mqozdx23ctzbmct5 --- addons/crm/__openerp__.py | 1 - addons/sale/__openerp__.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index ba05cc1fb16..3c87e36e389 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -128,7 +128,6 @@ Dashboard for CRM will include: 'application': True, 'auto_install': False, 'images': [ - 'images/crm_dashboard.png', 'images/customers.png', 'images/leads.png', 'images/opportunities_kanban.png', diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 8c5e506047e..1d698c17163 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -58,7 +58,7 @@ The Dashboard for the Sales Manager will include """, 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', - 'images': ['images/sale_dashboard.jpeg','images/Sale_order_line_to_invoice.jpeg','images/sale_order.jpeg','images/sales_analysis.jpeg'], + 'images': ['images/Sale_order_line_to_invoice.jpeg','images/sale_order.jpeg','images/sales_analysis.jpeg'], 'depends': ['account_voucher'], 'data': [ 'wizard/sale_make_invoice_advance.xml', From 30170062ddcb294b38cbe2dcdd0eb69f768b43d1 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 10:16:32 +0530 Subject: [PATCH 028/423] [rem]:mrp:remove mrp dashboard bzr revid: sunilsharma.sharma07@gmail.com-20140130044632-m0kw1a8ya466tlg3 --- addons/mrp/__openerp__.py | 3 +- addons/mrp/board_manufacturing_view.xml | 37 ------------------------- 2 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 addons/mrp/board_manufacturing_view.xml diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 99afd01707a..765eae6da61 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -28,7 +28,7 @@ 'category': 'Manufacturing', 'sequence': 18, 'summary': 'Manufacturing Orders, Bill of Materials, Routing', - 'images': ['images/bill_of_materials.jpeg', 'images/manufacturing_order.jpeg', 'images/planning_manufacturing_order.jpeg', 'images/manufacturing_analysis.jpeg', 'images/production_dashboard.jpeg','images/routings.jpeg','images/work_centers.jpeg'], + 'images': ['images/bill_of_materials.jpeg', 'images/manufacturing_order.jpeg', 'images/planning_manufacturing_order.jpeg', 'images/manufacturing_analysis.jpeg','images/routings.jpeg','images/work_centers.jpeg'], 'depends': ['product','procurement', 'stock', 'resource', 'purchase','process'], 'description': """ Manage the Manufacturing process in OpenERP @@ -70,7 +70,6 @@ Dashboard / Reports for MRP will include: 'process/procurement_process.xml', 'report/mrp_report_view.xml', 'report/mrp_production_order_view.xml', - 'board_manufacturing_view.xml', 'res_config_view.xml', ], 'demo': ['mrp_demo.xml'], diff --git a/addons/mrp/board_manufacturing_view.xml b/addons/mrp/board_manufacturing_view.xml deleted file mode 100644 index 6bd07c2648b..00000000000 --- a/addons/mrp/board_manufacturing_view.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - board.mrp.manager.form - board.board - -
- - - - - - - - -
-
-
- - - Manufacturing - board.board - form - form - - - - - -
-
From 742c1b22d1459db2691e0471e11c366aa2916788 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 10:46:11 +0530 Subject: [PATCH 030/423] [rem]:project and project_issue:remove project and project_issue dashboard and images bzr revid: sunilsharma.sharma07@gmail.com-20140130051611-b0m9zioykhlbi8jh --- addons/project/__openerp__.py | 2 - addons/project/board_project_view.xml | 64 ------------------- addons/project_issue/__openerp__.py | 1 - .../board_project_issue_view.xml | 45 ------------- 4 files changed, 112 deletions(-) delete mode 100644 addons/project/board_project_view.xml delete mode 100644 addons/project_issue/board_project_issue_view.xml diff --git a/addons/project/__openerp__.py b/addons/project/__openerp__.py index f5ba24c41cb..4247aa6ea2c 100644 --- a/addons/project/__openerp__.py +++ b/addons/project/__openerp__.py @@ -29,7 +29,6 @@ 'summary': 'Projects, Tasks', 'images': [ 'images/gantt.png', - 'images/project_dashboard.jpeg', 'images/project_task_tree.jpeg', 'images/project_task.jpeg', 'images/project.jpeg', @@ -72,7 +71,6 @@ Dashboard / Reports for Project Management will include: 'res_partner_view.xml', 'report/project_report_view.xml', 'report/project_cumulative.xml', - 'board_project_view.xml', 'res_config_view.xml', ], 'demo': ['project_demo.xml'], diff --git a/addons/project/board_project_view.xml b/addons/project/board_project_view.xml deleted file mode 100644 index 3a14f7b6274..00000000000 --- a/addons/project/board_project_view.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - project.task.tree - project.task - - - - - - - - - - - - - - - - - My Tasks - project.task - form - tree,form - [('user_id', '=', uid), ('stage_id.fold', '!=', True)] - - - - - board.project.form - board.board - -
- - - - - - - - -
-
-
- - - Project - board.board - form - form - menu - - - - - -
-
diff --git a/addons/project_issue/__openerp__.py b/addons/project_issue/__openerp__.py index 146cff0a407..97b6f736f54 100644 --- a/addons/project_issue/__openerp__.py +++ b/addons/project_issue/__openerp__.py @@ -46,7 +46,6 @@ It allows the manager to quickly check the issues, assign them and decide on the 'report/project_issue_report_view.xml', 'security/project_issue_security.xml', 'security/ir.model.access.csv', - 'board_project_issue_view.xml', 'res_config_view.xml', 'project_issue_data.xml' ], diff --git a/addons/project_issue/board_project_issue_view.xml b/addons/project_issue/board_project_issue_view.xml deleted file mode 100644 index 6eb48f5572d..00000000000 --- a/addons/project_issue/board_project_issue_view.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Project Issue Board Tree - project.issue - - - - - - - - - - - - - - - - - - - My Project Issues - project.issue - form - tree,form - [('user_id', '=', uid)] - - - - - board.my.project.issue.form.inherit - board.board - - - - - - - - - From 18e1f423ae65f77073afd78393684f149b508982 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 10:53:23 +0530 Subject: [PATCH 031/423] [rem]:event:remove event dashboard bzr revid: sunilsharma.sharma07@gmail.com-20140130052323-702ji8w2lowhyzer --- addons/event/__openerp__.py | 1 - addons/event/board_association_view.xml | 74 ------------------------- 2 files changed, 75 deletions(-) delete mode 100644 addons/event/board_association_view.xml diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py index e8ecb09bf03..15cd863dc55 100644 --- a/addons/event/__openerp__.py +++ b/addons/event/__openerp__.py @@ -47,7 +47,6 @@ Key Features 'event_view.xml', 'event_data.xml', 'report/report_event_registration_view.xml', - 'board_association_view.xml', 'res_partner_view.xml', 'email_template.xml', ], diff --git a/addons/event/board_association_view.xml b/addons/event/board_association_view.xml deleted file mode 100644 index f48722bfea6..00000000000 --- a/addons/event/board_association_view.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - Registration Event report - report.event.registration - - - - - - - - - - Events Filling Status - report.event.registration - form - [('event_state','not in',('cancel','done'))] - graph,tree - - - - - Next Events - ir.actions.act_window - event.event - form - tree,form - [('state','not in',('cancel','done'))] - - - - New Registration - ir.actions.act_window - event.registration - form - tree,form - [('state','=','draft')] - - - - board.associations.manager.form - board.board - -
- - - - - - - - -
-
-
- - - Events - board.board - form - form - - - - -
-
From 8ae9f5fa1d787a9e497f219066fa96dcd1b18bdc Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 11:09:17 +0530 Subject: [PATCH 032/423] [rem]:account:remove account dashboard bzr revid: sunilsharma.sharma07@gmail.com-20140130053917-8n5b9vh7rf2k5cv4 --- addons/account/__openerp__.py | 1 - addons/account/board_account_view.xml | 46 --------------------------- 2 files changed, 47 deletions(-) delete mode 100644 addons/account/board_account_view.xml diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 343512dc271..e372c58c759 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -119,7 +119,6 @@ for a particular financial year and for preparation of vouchers there is a modul 'process/supplier_invoice_process.xml', 'ir_sequence_view.xml', 'company_view.xml', - 'board_account_view.xml', 'edi/invoice_action_data.xml', 'account_bank_view.xml', 'res_config_view.xml', diff --git a/addons/account/board_account_view.xml b/addons/account/board_account_view.xml deleted file mode 100644 index abbc81ade2b..00000000000 --- a/addons/account/board_account_view.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Company Analysis - account.entries.report - form - tree,graph - {'group_by':['user_type'], 'group_by_no_leaf':1} - - [('year','=',time.strftime('%Y'))] - - - - board.account.form - board.board - -
- - - - - -
-
-
- - - Accounting - board.board - form - form - menu - - - - - -
-
From efe7f2ba00b9a845b83d34117fb8d023c2af9d3a Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 11:20:32 +0530 Subject: [PATCH 033/423] [rem]:fleet:remove fleet dashboard bzr revid: sunilsharma.sharma07@gmail.com-20140130055032-79lxdzeqfrzda3l4 --- addons/fleet/__openerp__.py | 1 - addons/fleet/fleet_board_view.xml | 154 ------------------------------ 2 files changed, 155 deletions(-) delete mode 100644 addons/fleet/fleet_board_view.xml diff --git a/addons/fleet/__openerp__.py b/addons/fleet/__openerp__.py index 29c0e9d3ceb..3edf8ea8e0d 100644 --- a/addons/fleet/__openerp__.py +++ b/addons/fleet/__openerp__.py @@ -54,7 +54,6 @@ Main Features 'fleet_view.xml', 'fleet_cars.xml', 'fleet_data.xml', - 'fleet_board_view.xml', ], 'images': ['images/costs_analysis.jpeg','images/indicative_costs_analysis.jpeg','images/vehicles.jpeg','images/vehicles_contracts.jpeg','images/vehicles_fuel.jpeg','images/vehicles_odometer.jpeg','images/vehicles_services.jpeg'], diff --git a/addons/fleet/fleet_board_view.xml b/addons/fleet/fleet_board_view.xml deleted file mode 100644 index 41093d2c283..00000000000 --- a/addons/fleet/fleet_board_view.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - - - Fuel Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','fuel')] - - - - Services Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','services')] - - - - Contracts Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','contract')] - - - - Costs by Month - fleet.vehicle.cost - - form - tree - [('parent_id','=',False)] - - - - Vehicles with alerts - fleet.vehicle - - form - tree - ['|',('contract_renewal_due_soon','=',True),('contract_renewal_overdue','=',True)] - -

- Here are displayed vehicles for which one or more contracts need to be renewed. If you see this message, then there is no contracts to renew. -

-
-
- - - Costs Analysis - fleet.vehicle.cost - - form - tree - {"search_default_parent_false" : True,"search_default_groupby_year" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_cost_subtype" : True, "search_default_groupby_vehicle_id" : True,} - -

- OpenERP helps you managing the costs for your different vehicles - Costs are generally created from services and contract and appears here. -

-

- Thanks to the different filters, OpenERP can only print the effective - costs, sort them by type and by vehicle. -

-
-
- - - Indicative Costs Analysis - fleet.vehicle.cost - - form - tree - {"search_default_parent_true" : True,"search_default_groupby_cost_subtype" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_parent_id" : True,} - -

- OpenERP helps you managing the costs for your different vehicles - Costs are generally created from services and contract and appears here. -

-

- Thanks to the different filters, OpenERP can only print the effective - costs, sort them by type and by vehicle. -

-
-
- - - board.fleet.form - board.board - -
- - - - - - - - - - - -
-
-
- - - Fleet - board.board - form - form - menu - - -
-

- Fleet dashboard is empty. -

- To add your first report into this dashboard, go to any - menu, switch to list or graph view, and click 'Add to - Dashboard' in the extended search options. -

- You can filter and group data before inserting into the - dashboard using the search options. -

-
-
-
- - - - - - - -
-
From a267d86b294315ef528e1a46465e5406827e8d62 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 12:19:23 +0530 Subject: [PATCH 034/423] [rem,imp]:hr:remove hr dashboard and improve hr view bzr revid: sunilsharma.sharma07@gmail.com-20140130064923-35tvo8q3sy4n09vx --- addons/hr/__openerp__.py | 1 - addons/hr/board_hr_view.xml | 49 ------------------- addons/hr/hr_view.xml | 1 + addons/hr_evaluation/__openerp__.py | 1 - .../board_hr_evaluation_view.xml | 26 ---------- addons/hr_expense/__openerp__.py | 1 - addons/hr_expense/board_hr_expense_view.xml | 26 ---------- addons/hr_holidays/__openerp__.py | 1 - addons/hr_holidays/board_hr_holidays_view.xml | 27 ---------- addons/hr_recruitment/__openerp__.py | 1 - .../board_hr_recruitment_statistical_view.xml | 41 ---------------- addons/hr_timesheet_sheet/__openerp__.py | 1 - .../board_hr_timesheet_view.xml | 37 -------------- 13 files changed, 1 insertion(+), 212 deletions(-) delete mode 100644 addons/hr/board_hr_view.xml delete mode 100644 addons/hr_evaluation/board_hr_evaluation_view.xml delete mode 100644 addons/hr_expense/board_hr_expense_view.xml delete mode 100644 addons/hr_holidays/board_hr_holidays_view.xml delete mode 100644 addons/hr_recruitment/board_hr_recruitment_statistical_view.xml delete mode 100644 addons/hr_timesheet_sheet/board_hr_timesheet_view.xml diff --git a/addons/hr/__openerp__.py b/addons/hr/__openerp__.py index ef7225788f6..b06497874d0 100644 --- a/addons/hr/__openerp__.py +++ b/addons/hr/__openerp__.py @@ -52,7 +52,6 @@ You can manage: 'data': [ 'security/hr_security.xml', 'security/ir.model.access.csv', - 'board_hr_view.xml', 'hr_view.xml', 'process/hr_process.xml', 'hr_installer.xml', diff --git a/addons/hr/board_hr_view.xml b/addons/hr/board_hr_view.xml deleted file mode 100644 index 84db6128f41..00000000000 --- a/addons/hr/board_hr_view.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - board.hr.form - board.board - -
- - - - -
-
-
- - - Human Resources - board.board - form - form - menu - - -
-

- Human Resources dashboard is empty. -

- To add your first report into this dashboard, go to any - menu, switch to list or graph view, and click 'Add to - Dashboard' in the extended search options. -

- You can filter and group data before inserting into the - dashboard using the search options. -

-
-
-
- - -
-
diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml index eea2eb2ce41..620593d20a9 100644 --- a/addons/hr/hr_view.xml +++ b/addons/hr/hr_view.xml @@ -7,6 +7,7 @@ id="menu_hr_root" groups="base.group_hr_manager,base.group_hr_user,base.group_user" sequence="90"/> + - - - - - Interview Requests - hr.evaluation.interview - form - - [('is_evaluation' ,'=', True), ('user_id', '=', uid),('state','=','waiting_answer')] - - - - - board.hr.evaluation.form - board.board - - - - - - - - - - diff --git a/addons/hr_expense/__openerp__.py b/addons/hr_expense/__openerp__.py index f149bc0c7c6..928d1827d95 100644 --- a/addons/hr_expense/__openerp__.py +++ b/addons/hr_expense/__openerp__.py @@ -57,7 +57,6 @@ This module also uses analytic accounting and is compatible with the invoice on 'process/hr_expense_process.xml', 'security/ir_rule.xml', 'report/hr_expense_report_view.xml', - 'board_hr_expense_view.xml', 'hr_expense_installer_view.xml', ], 'demo': ['hr_expense_demo.xml'], diff --git a/addons/hr_expense/board_hr_expense_view.xml b/addons/hr_expense/board_hr_expense_view.xml deleted file mode 100644 index 3f896a76fae..00000000000 --- a/addons/hr_expense/board_hr_expense_view.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - My Expenses - hr.expense.expense - form - [('state','in',('confirm', 'accepted')),('user_id','=',uid)] - {'default_user_id': uid} - - - - - board.hr.expense.form - board.board - - - - - - - - - - diff --git a/addons/hr_holidays/__openerp__.py b/addons/hr_holidays/__openerp__.py index 5d57dbab87e..eec73fe07e5 100644 --- a/addons/hr_holidays/__openerp__.py +++ b/addons/hr_holidays/__openerp__.py @@ -57,7 +57,6 @@ A synchronization with an internal agenda (Meetings of the CRM module) is also p 'report/available_holidays_view.xml', 'wizard/hr_holidays_summary_department_view.xml', 'wizard/hr_holidays_summary_employees_view.xml', - 'board_hr_holidays_view.xml', ], 'demo': ['hr_holidays_demo.xml',], 'js': ['static/src/js/*.js'], diff --git a/addons/hr_holidays/board_hr_holidays_view.xml b/addons/hr_holidays/board_hr_holidays_view.xml deleted file mode 100644 index c90ee32c396..00000000000 --- a/addons/hr_holidays/board_hr_holidays_view.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - My Leaves - hr.holidays.status - form - tree,form - - {} - [] - - - - board.hr.holidays.leave.month.form - board.board - - - - - - - - - - diff --git a/addons/hr_recruitment/__openerp__.py b/addons/hr_recruitment/__openerp__.py index cb1dd54e902..4697a9e6aac 100644 --- a/addons/hr_recruitment/__openerp__.py +++ b/addons/hr_recruitment/__openerp__.py @@ -52,7 +52,6 @@ You can define the different phases of interviews and easily rate the applicant 'security/hr_recruitment_security.xml', 'security/ir.model.access.csv', 'report/hr_recruitment_report_view.xml', - 'board_hr_recruitment_statistical_view.xml', 'hr_recruitment_installer_view.xml', 'res_config_view.xml', 'hr_recruitment_data.xml', diff --git a/addons/hr_recruitment/board_hr_recruitment_statistical_view.xml b/addons/hr_recruitment/board_hr_recruitment_statistical_view.xml deleted file mode 100644 index 2bec80858a5..00000000000 --- a/addons/hr_recruitment/board_hr_recruitment_statistical_view.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - applicants.status.tree - hr.applicant - - - - - - - - - - - - - Applicants Status - ir.actions.act_window - hr.applicant - form - tree,form - [('stage_id.fold', '!=', True)] - - - - - board.hr.applicants.status.form - board.board - - - - - - - - - - diff --git a/addons/hr_timesheet_sheet/__openerp__.py b/addons/hr_timesheet_sheet/__openerp__.py index e92ab4400bd..0853e81690d 100644 --- a/addons/hr_timesheet_sheet/__openerp__.py +++ b/addons/hr_timesheet_sheet/__openerp__.py @@ -53,7 +53,6 @@ The validation can be configured in the company: 'hr_timesheet_sheet_view.xml', 'hr_timesheet_workflow.xml', 'process/hr_timesheet_sheet_process.xml', - 'board_hr_timesheet_view.xml', 'report/hr_timesheet_report_view.xml', 'report/timesheet_report_view.xml', 'wizard/hr_timesheet_current_view.xml', diff --git a/addons/hr_timesheet_sheet/board_hr_timesheet_view.xml b/addons/hr_timesheet_sheet/board_hr_timesheet_view.xml deleted file mode 100644 index 145d118ceb7..00000000000 --- a/addons/hr_timesheet_sheet/board_hr_timesheet_view.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - hr.timesheet.sheet.sheet.graph - hr_timesheet_sheet.sheet - - - - - - - - - - My Total Attendances By Week - hr_timesheet_sheet.sheet - form - graph - [('user_id','=',uid)] - - - - - board.hr.timesheet.sheet.form - board.board - - - - - - - - - - From bd31663a172d97c06f79a679d9fc814ec212f002 Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Thu, 30 Jan 2014 15:37:35 +0530 Subject: [PATCH 035/423] [imp]:fleet:improve fleet view bzr revid: sunilsharma.sharma07@gmail.com-20140130100735-pjs8eo6hhgp3i7zg --- addons/fleet/__openerp__.py | 1 + addons/fleet/fleet_board_view.xml | 57 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 addons/fleet/fleet_board_view.xml diff --git a/addons/fleet/__openerp__.py b/addons/fleet/__openerp__.py index 3edf8ea8e0d..29c0e9d3ceb 100644 --- a/addons/fleet/__openerp__.py +++ b/addons/fleet/__openerp__.py @@ -54,6 +54,7 @@ Main Features 'fleet_view.xml', 'fleet_cars.xml', 'fleet_data.xml', + 'fleet_board_view.xml', ], 'images': ['images/costs_analysis.jpeg','images/indicative_costs_analysis.jpeg','images/vehicles.jpeg','images/vehicles_contracts.jpeg','images/vehicles_fuel.jpeg','images/vehicles_odometer.jpeg','images/vehicles_services.jpeg'], diff --git a/addons/fleet/fleet_board_view.xml b/addons/fleet/fleet_board_view.xml new file mode 100644 index 00000000000..e657d904d64 --- /dev/null +++ b/addons/fleet/fleet_board_view.xml @@ -0,0 +1,57 @@ + + + + + + Costs Analysis + fleet.vehicle.cost + + form + tree + {"search_default_parent_false" : True,"search_default_groupby_year" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_cost_subtype" : True, "search_default_groupby_vehicle_id" : True,} + +

+ OpenERP helps you managing the costs for your different vehicles + Costs are generally created from services and contract and appears here. +

+

+ Thanks to the different filters, OpenERP can only print the effective + costs, sort them by type and by vehicle. +

+
+
+ + + Indicative Costs Analysis + fleet.vehicle.cost + + form + tree + {"search_default_parent_true" : True,"search_default_groupby_cost_subtype" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_parent_id" : True,} + +

+ OpenERP helps you managing the costs for your different vehicles + Costs are generally created from services and contract and appears here. +

+

+ Thanks to the different filters, OpenERP can only print the effective + costs, sort them by type and by vehicle. +

+
+
+ + + + + + +
+
From 16c05082c8c062b02b566acc4d1bc9ec85476e3e Mon Sep 17 00:00:00 2001 From: "Sunil Sharma (OpenERP)" Date: Tue, 4 Mar 2014 12:38:10 +0530 Subject: [PATCH 036/423] [remove]:mrp dashboard file bzr revid: sunilsharma.sharma07@gmail.com-20140304070810-282vhtpg3mduym0j --- addons/mrp/__openerp__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 5b625486e9c..73985b7a4d8 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -69,7 +69,6 @@ Dashboard / Reports for MRP will include: 'process/service_product_process.xml', 'process/procurement_process.xml', 'report/mrp_report_view.xml', - 'board_manufacturing_view.xml', 'res_config_view.xml', 'views/report_mrporder.xml', From c2a92a5be2478960e18217dd8bbe951b0b74a2c8 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Mar 2014 14:24:47 +0530 Subject: [PATCH 037/423] [IMP] remove menu_id from user model bzr revid: rajmyt@gmail.com-20140304085447-zknvpkfe4i3d8uku --- openerp/addons/base/base_data.xml | 1 - openerp/addons/base/res/res_users.py | 15 +-------------- openerp/addons/base/res/res_users_view.xml | 4 ---- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index b6c12e111ff..96e13773cae 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -75,7 +75,6 @@ - -- Administrator diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index b2aba694078..fad3691a831 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -154,8 +154,6 @@ class res_users(osv.osv): "a change of password, the user has to login again."), 'signature': fields.text('Signature'), 'active': fields.boolean('Active'), - 'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."), - 'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."), 'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'), # Special behavior for this field: res.company.search() will only return the companies # available to the current user (should be the user's companies?), when the user_preference @@ -216,16 +214,6 @@ class res_users(osv.osv): return [c] return False - def _get_menu(self,cr, uid, context=None): - dataobj = self.pool.get('ir.model.data') - try: - model, res_id = dataobj.get_object_reference(cr, uid, 'base', 'action_menu_admin') - if model != 'ir.actions.act_window': - return False - return res_id - except ValueError: - return False - def _get_group(self,cr, uid, context=None): dataobj = self.pool.get('ir.model.data') result = [] @@ -243,7 +231,6 @@ class res_users(osv.osv): 'password': '', 'active': True, 'customer': False, - 'menu_id': _get_menu, 'company_id': _get_company, 'company_ids': _get_companies, 'groups_id': _get_group, @@ -251,7 +238,7 @@ class res_users(osv.osv): } # User can write on a few of his own fields (but not his groups for example) - SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz'] + SELF_WRITEABLE_FIELDS = ['password', 'signature', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz'] # User can read a few of his own fields SELF_READABLE_FIELDS = ['signature', 'company_id', 'login', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz', 'tz_offset', 'groups_id', 'partner_id', '__last_update'] diff --git a/openerp/addons/base/res/res_users_view.xml b/openerp/addons/base/res/res_users_view.xml index ba603c7a0f0..bb47f022a08 100644 --- a/openerp/addons/base/res/res_users_view.xml +++ b/openerp/addons/base/res/res_users_view.xml @@ -199,10 +199,6 @@ - - - - From 8c666af35c9c7b79373b999d1df2d4ba350e8f5d Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Mar 2014 14:26:59 +0530 Subject: [PATCH 038/423] [IMP] remove menu_id from user model bzr revid: rajmyt@gmail.com-20140304085659-lufot16ae59y1jca --- addons/web/controllers/main.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index a9f56a2099c..d1e450cc34f 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1054,16 +1054,7 @@ class Menu(http.Controller): """ s = request.session Menus = s.model('ir.ui.menu') - # If a menu action is defined use its domain to get the root menu items - user_menu_id = s.model('res.users').read([s.uid], ['menu_id'], - request.context)[0]['menu_id'] - menu_domain = [('parent_id', '=', False)] - if user_menu_id: - domain_string = s.model('ir.actions.act_window').read( - [user_menu_id[0]], ['domain'],request.context)[0]['domain'] - if domain_string: - menu_domain = ast.literal_eval(domain_string) return Menus.search(menu_domain, 0, False, False, request.context) From 9b74e8054eaafa2ec1a21d9e9291b24bdb81b2d2 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Mar 2014 15:20:57 +0530 Subject: [PATCH 039/423] [IMP] remove fleet dashboard bzr revid: rajmyt@gmail.com-20140304095057-3i12fqxqz673z6i8 --- addons/fleet/fleet_board_view.xml | 99 ------------------------------- 1 file changed, 99 deletions(-) diff --git a/addons/fleet/fleet_board_view.xml b/addons/fleet/fleet_board_view.xml index c4732d9a0f4..9530ee0dd38 100644 --- a/addons/fleet/fleet_board_view.xml +++ b/addons/fleet/fleet_board_view.xml @@ -1,56 +1,6 @@ - - Fuel Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','fuel')] - - - - Services Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','services')] - - - - Contracts Costs by Month - fleet.vehicle.cost - - form - tree - ['&',('parent_id','=',False),('cost_type','=','contract')] - - - - Costs by Month - fleet.vehicle.cost - - form - tree - [('parent_id','=',False)] - - - - Vehicles with alerts - fleet.vehicle - - form - tree - ['|',('contract_renewal_due_soon','=',True),('contract_renewal_overdue','=',True)] - -

- Here are displayed vehicles for which one or more contracts need to be renewed. If you see this message, then there is no contracts to renew. -

-
-
- Costs Analysis fleet.vehicle.cost @@ -88,55 +38,6 @@

- - - board.fleet.form - board.board - -
- - - - - - - - - - - -
-
-
- - - Fleet - board.board - form - form - menu - - -
-

- Fleet dashboard is empty. -

- To add your first report into this dashboard, go to any - menu, switch to list or graph view, and click 'Add to - Dashboard' in the extended search options. -

- You can filter and group data before inserting into the - dashboard using the search options. -

-
-
-
- - From 84ed653322aa379ace94081dfde12ecc96bc485e Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Tue, 4 Mar 2014 17:59:31 +0530 Subject: [PATCH 040/423] [IMP] remove tree view from task_hours_per_month report bzr revid: rajmyt@gmail.com-20140304122931-ektojfe9yvlxeiba --- .../report/task_report_view.xml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/addons/project_timesheet/report/task_report_view.xml b/addons/project_timesheet/report/task_report_view.xml index 2c8a34c656e..37d7b1486f9 100644 --- a/addons/project_timesheet/report/task_report_view.xml +++ b/addons/project_timesheet/report/task_report_view.xml @@ -9,20 +9,6 @@ - - report.timesheet.task.user.tree - report.timesheet.task.user - - - - - - - - - - - report.timesheet.task.user.search report.timesheet.task.user @@ -55,7 +41,7 @@ Task Hours Per Month report.timesheet.task.user form - tree,graph + graph {'search_default_year':1,'search_default_month':1, 'search_default_group_user_id':1} Date: Tue, 4 Mar 2014 18:37:27 +0530 Subject: [PATCH 041/423] [IMP] remove list view from member analysis report bzr revid: rajmyt@gmail.com-20140304130727-heez8ub1x4jq4dxw --- addons/membership/report/report_membership_view.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/membership/report/report_membership_view.xml b/addons/membership/report/report_membership_view.xml index 50b579d9ec2..100ec32043f 100644 --- a/addons/membership/report/report_membership_view.xml +++ b/addons/membership/report/report_membership_view.xml @@ -49,6 +49,7 @@ Members Analysis report.membership form + graph {"search_default_year":1,"search_default_member":1, 'search_default_Revenue':1, 'search_default_this_month':1, 'search_default_salesman':1,'group_by_no_leaf':1} From b7bc8b3aa45b66245c1b65461543d8c4f4fed46e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 12 Mar 2014 14:23:47 +0100 Subject: [PATCH 042/423] [IMP] change the partner form view to display new stat button information in addon account/crm bzr revid: ged@openerp.com-20140312132347-dyu1i3szlh9r7jq9 --- addons/account/account_invoice.py | 2 +- addons/account/partner.py | 21 +++++++++++++++++++++ addons/account/partner_view.xml | 11 ++++++++--- addons/crm/res_partner.py | 18 +++++++++++++++++- addons/crm/res_partner_view.xml | 22 +++++++++++++++------- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 06e59232ac9..5a0e1411fe8 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1801,7 +1801,7 @@ class res_partner(osv.osv): """ Inherits partner and adds invoice information in the partner form """ _inherit = 'res.partner' _columns = { - 'invoice_ids': fields.one2many('account.invoice.line', 'partner_id', 'Invoices', readonly=True), + 'invoice_ids': fields.one2many('account.invoice', 'partner_id', 'Invoices', readonly=True), } def _find_accounting_partner(self, partner): diff --git a/addons/account/partner.py b/addons/account/partner.py index f24ffcf55b4..d3777683f6f 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -162,6 +162,24 @@ class res_partner(osv.osv): def _debit_search(self, cr, uid, obj, name, args, context=None): return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) + def _invoices_stat_button(self, cr, uid, ids, field_name, arg, context=None): + res = {} + obj = self.pool.get('account.invoice') + for partner in self.browse(cr, uid, ids, context): + domain = [('id', 'in', map(int, partner.invoice_ids))] + group_obj = obj.read_group(cr, uid, domain, ['amount_total'], [''], context=context) + total = group_obj[0]['amount_total'] + res[partner.id] = """ +
%s invoices
+
Total: %s
+ """ % (len(partner.invoice_ids), total) + return res + + def _journal_items_stat_button(self, cr, uid, ids, field_name, arg, context=None): + html = "
%s Journal Items
" + return {partner.id: html % len(partner.journal_items_ids) for partner in self.browse(cr, uid, ids, context)} + res = {} + def has_something_to_reconcile(self, cr, uid, partner_id, context=None): ''' at least a debit, a credit and a line older than the last reconciliation date of the partner @@ -190,6 +208,9 @@ class res_partner(osv.osv): fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."), 'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, string='Total Payable', multi='dc', help="Total amount you have to pay to this supplier."), 'debit_limit': fields.float('Payable Limit'), + 'invoices_stat_button': fields.function(_invoices_stat_button, string="Invoices", type='html'), + 'journal_items_ids': fields.one2many('account.move.line', 'partner_id', 'Journal Items'), + 'journal_items_stat_button': fields.function(_journal_items_stat_button, string='Journal Items', type='html'), 'property_account_payable': fields.property( type='many2one', relation='account.account', diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml index 6a58bc7f77e..448a093570f 100644 --- a/addons/account/partner_view.xml +++ b/addons/account/partner_view.xml @@ -64,10 +64,15 @@ - + + + From aac67e8bc528ea9c7bc771428bba952c984bf8ab Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 17 Mar 2014 16:28:28 +0100 Subject: [PATCH 046/423] [IMP] removes the testing field testpercent in res.partner and improves the way the buttons are displayed in form view (addon account) bzr revid: ged@openerp.com-20140317152828-v2den23s32kzaqxh --- addons/account/partner.py | 21 +++------------------ addons/account/partner_view.xml | 4 ++-- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/addons/account/partner.py b/addons/account/partner.py index cad285def84..b0092e5403a 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -21,7 +21,6 @@ from operator import itemgetter import time -import random from openerp.osv import fields, osv @@ -163,21 +162,8 @@ class res_partner(osv.osv): def _debit_search(self, cr, uid, obj, name, args, context=None): return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) - def _invoices_stat_button(self, cr, uid, ids, field_name, arg, context=None): - res = {} - obj = self.pool.get('account.invoice') - for partner in self.browse(cr, uid, ids, context): - domain = [('id', 'in', map(int, partner.invoice_ids))] - group_obj = obj.read_group(cr, uid, domain, ['amount_total'], [''], context=context) - total = group_obj[0]['amount_total'] or 0 - res[partner.id] = """ -
%s Invoices
-
Total: %s
- """ % (len(partner.invoice_ids), total) - return res - - def _test_percent(self, cr, uid, ids, field_name, arg, context=None): - return {partner.id: random.random()*100 for partner in self.browse(cr, uid, ids, context)} + def _invoice_count(self, cr, uid, ids, field_name, arg, context=None): + return {partner.id: len(partner.invoice_ids) for partner in self.browse(cr, uid, ids, context)} def _journal_item_count(self, cr, uid, ids, field_name, arg, context=None): return {partner.id: len(partner.journal_items_ids) for partner in self.browse(cr, uid, ids, context)} @@ -210,8 +196,7 @@ class res_partner(osv.osv): fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."), 'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, string='Total Payable', multi='dc', help="Total amount you have to pay to this supplier."), 'debit_limit': fields.float('Payable Limit'), - 'invoices_stat_button': fields.function(_invoices_stat_button, string="Invoices", type='html'), - 'testpercent': fields.function(_test_percent, string="TestPercent", type='float'), + 'invoice_count': fields.function(_invoice_count, string="Invoices", type='html'), 'journal_items_ids': fields.one2many('account.move.line', 'partner_id', 'Journal Items'), 'journal_item_count': fields.function(_journal_item_count, string="Journal Items", type="integer"), 'property_account_payable': fields.property( diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml index 472e14a806f..b64f2a4f88c 100644 --- a/addons/account/partner_view.xml +++ b/addons/account/partner_view.xml @@ -66,10 +66,10 @@
- - +
@@ -238,7 +243,7 @@ - + diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 6f072f5abd1..69ceb7839ca 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -490,22 +490,27 @@ class project(osv.Model): def _get_alias_models(self, cr, uid, context=None): return [('project.task', "Tasks"), ("project.issue", "Issues")] - def _issue_count(self, cr, uid, ids, field_name, arg, context=None): - """ :deprecated: this method will be removed with OpenERP v8. Use issue_ids - fields instead. """ - res = dict.fromkeys(ids, 0) - issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)]) - for issue in self.pool.get('project.issue').browse(cr, uid, issue_ids, context): - if issue.stage_id and not issue.stage_id.fold: - res[issue.project_id.id] += 1 +# def _issue_count(self, cr, uid, ids, field_name, arg, context=None): +# """ :deprecated: this method will be removed with OpenERP v8. Use issue_ids +# fields instead. """ +# res = dict.fromkeys(ids, 0) +# issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)]) +# for issue in self.pool.get('project.issue').browse(cr, uid, issue_ids, context): +# if issue.stage_id and not issue.stage_id.fold: +# res[issue.project_id.id] += 1 +# return res + def _total_issue_count(self, cr, uid, ids, field_name, arg, context=None): + res={} + for issues in self.browse(cr, uid, ids, context): + res[issues.id] = len(issues.issue_ids) return res - _columns = { 'project_escalation_id': fields.many2one('project.project', 'Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}), - 'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues", - deprecated="This field will be removed in OpenERP v8. Use issue_ids one2many field instead."), +# 'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues", +# deprecated="This field will be removed in OpenERP v8. Use issue_ids one2many field instead."), + 'total_issue_count': fields.function(_total_issue_count, string="Issue", type='integer'), 'issue_ids': fields.one2many('project.issue', 'project_id', domain=[('stage_id.fold', '=', False)]) } diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index 3af9ee608d6..2b2c48519f9 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -306,7 +306,10 @@ diff --git a/addons/project_timesheet/project_timesheet_view.xml b/addons/project_timesheet/project_timesheet_view.xml index 548264eb07b..a51c7976602 100644 --- a/addons/project_timesheet/project_timesheet_view.xml +++ b/addons/project_timesheet/project_timesheet_view.xml @@ -30,7 +30,10 @@ From 6cd8ef5c6597068cfcca25ddbdcdee0d1ede0a34 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Thu, 20 Mar 2014 15:19:59 +0530 Subject: [PATCH 053/423] [IMP] add icons for stat buttons bzr revid: rajmyt@gmail.com-20140320094959-4vki69r7715xvl41 --- addons/web/static/lib/fontawesome/css/font-awesome.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/web/static/lib/fontawesome/css/font-awesome.css b/addons/web/static/lib/fontawesome/css/font-awesome.css index 7fa0e6f467b..9e1011e7ef2 100644 --- a/addons/web/static/lib/fontawesome/css/font-awesome.css +++ b/addons/web/static/lib/fontawesome/css/font-awesome.css @@ -207,6 +207,9 @@ .fa-star:before { content: "\f005"; } +. fa-tasks:before { + content: "\f0ae"; +} .fa-star-o:before { content: "\f006"; } @@ -308,6 +311,9 @@ .fa-qrcode:before { content: "\f029"; } +.fa-calendar:before { + content: "\f073"; +} .fa-barcode:before { content: "\f02a"; } From df53c3f970d948321dc91de7e2818decce94adbe Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Thu, 20 Mar 2014 16:50:17 +0530 Subject: [PATCH 054/423] [IMP] improve code bzr revid: rma@tinyerp.com-20140320112017-03miv5s8jovz0iac --- addons/project/project.py | 19 ++----------------- addons/project/project_view.xml | 4 ++-- addons/project_issue/project_issue.py | 15 ++------------- addons/project_issue/project_issue_view.xml | 2 +- 4 files changed, 7 insertions(+), 33 deletions(-) diff --git a/addons/project/project.py b/addons/project/project.py index ee6390e4b87..942a47d06a6 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -186,20 +186,7 @@ class project(osv.osv): task_attachments = attachment.search(cr, uid, [('res_model', '=', 'project.task'), ('res_id', 'in', task_ids)], context=context, count=True) res[id] = (project_attachments or 0) + (task_attachments or 0) return res - -# def _task_count(self, cr, uid, ids, field_name, arg, context=None): -# """ :deprecated: this method will be removed with OpenERP v8. Use task_ids -# fields instead. """ -# if context is None: -# context = {} -# res = dict.fromkeys(ids, 0) -# ctx = context.copy() -# ctx['active_test'] = False -# task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)], context=ctx) -# for task in self.pool.get('project.task').browse(cr, uid, task_ids, context): -# res[task.project_id.id] += 1 -# return res - def _total_task_count(self, cr, uid, ids, field_name, arg, context=None): + def _task_count(self, cr, uid, ids, field_name, arg, context=None): res={} for tasks in self.browse(cr, uid, ids, context): res[tasks.id] = len(tasks.task_ids) @@ -269,8 +256,7 @@ class project(osv.osv): }), 'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ), 'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), -# 'task_count': fields.function(_task_count, type='integer', string="Open Tasks", -# deprecated="This field will be removed in OpenERP v8. Use task_ids one2many field instead."), + 'task_count': fields.function(_task_count, type='integer', string="Tasks",), 'task_ids': fields.one2many('project.task', 'project_id', domain=[('stage_id.fold', '=', False)]), 'color': fields.integer('Color Index'), @@ -292,7 +278,6 @@ class project(osv.osv): " is activated, portal users see the followed tasks or issues."), 'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','Pending'),('close','Closed')], 'Status', required=True,), 'doc_count':fields.function(_get_attached_docs, string="Number of documents attached", type='int'), - 'total_task_count': fields.function(_total_task_count, string="Task", type='integer'), } def _get_type_common(self, cr, uid, context): diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index 45fe175f515..35d4e1bf64f 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -95,7 +95,7 @@
From b51066b500e069142df47cf03c045b2b068872a7 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Thu, 20 Mar 2014 19:14:14 +0530 Subject: [PATCH 055/423] [IMP] convert button into stat button for customer bzr revid: rma@tinyerp.com-20140320134414-mk1ie8okynrtudsq --- addons/account/partner.py | 4 +++- addons/account/partner_view.xml | 6 ++++-- addons/project/res_partner.py | 11 ++++++++++- addons/project/res_partner_view.xml | 10 ++++++---- addons/project_issue/project_issue.py | 17 ++++++++++++++++- addons/project_issue/project_issue_view.xml | 11 +++++++---- addons/sale/res_partner_view.xml | 7 ++++--- 7 files changed, 50 insertions(+), 16 deletions(-) diff --git a/addons/account/partner.py b/addons/account/partner.py index 0c3395de1b2..6ae83368143 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -163,13 +163,14 @@ class res_partner(osv.osv): return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) def _invoice_journal_item_count(self, cr, uid, ids, field_name, arg, context=None): - res = dict(map(lambda x: (x,{'invoice_count': 0, 'journal_item_count': 0}), ids)) + res = dict(map(lambda x: (x,{'invoice_count': 0, 'journal_item_count': 0, 'cotracts_count': 0 }), ids)) # the user may not have access rights try: for partner in self.browse(cr, uid, ids, context): res[partner.id] = { 'invoice_count': len(partner.invoice_ids), 'journal_item_count': len(partner.journal_item_ids), + 'cotracts_count': len(partner.contract_ids) } except: pass @@ -204,6 +205,7 @@ class res_partner(osv.osv): 'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, string='Total Payable', multi='dc', help="Total amount you have to pay to this supplier."), 'debit_limit': fields.float('Payable Limit'), 'invoice_count': fields.function(_invoice_journal_item_count, string="Invoices", type='integer', multi="invoice_journal"), + 'cotracts_count': fields.function(_invoice_journal_item_count, string="Contracts", type='integer', multi="invoice_journal"), 'journal_item_ids': fields.one2many('account.move.line', 'partner_id', 'Journal Items'), 'journal_item_count': fields.function(_invoice_journal_item_count, string="Journal Items", type="integer", multi="invoice_journal"), 'property_account_payable': fields.property( diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml index b64f2a4f88c..8dbda70ec6b 100644 --- a/addons/account/partner_view.xml +++ b/addons/account/partner_view.xml @@ -74,8 +74,10 @@ - diff --git a/addons/project/res_partner.py b/addons/project/res_partner.py index e49cacf4f89..79af0413385 100644 --- a/addons/project/res_partner.py +++ b/addons/project/res_partner.py @@ -22,11 +22,20 @@ from openerp.osv import fields,osv class res_partner(osv.osv): - + def _task_count(self, cr, uid, ids, field_name, arg, context=None): + res = dict(map(lambda x: (x,0), ids)) + try: + for partner in self.browse(cr, uid, ids, context): + res[partner.id] = len(partner.task_ids) + except: + pass + return res + """ Inherits partner and adds Tasks information in the partner form """ _inherit = 'res.partner' _columns = { 'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'), + 'task_count': fields.function(_task_count, string='# Tasks', type='integer'), } def copy(self, cr, uid, record_id, default=None, context=None): diff --git a/addons/project/res_partner_view.xml b/addons/project/res_partner_view.xml index f12189b5163..a77ea467dcb 100644 --- a/addons/project/res_partner_view.xml +++ b/addons/project/res_partner_view.xml @@ -10,11 +10,13 @@ - + + diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index c4c35b2b712..947aba44242 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -569,5 +569,20 @@ class project_project(osv.Model): self._check_create_write_values(cr, uid, vals, context=context) return super(project_project, self).write(cr, uid, ids, vals, context=context) - +class res_partner(osv.osv): + def _issue_count(self, cr, uid, ids, field_name, arg, context=None): + res = dict(map(lambda x: (x,0), ids)) + try: + for partner in self.browse(cr, uid, ids, context): + res[partner.id] = len(partner.issue_ids) + except: + pass + return res + + """ Inherits partner and adds Tasks information in the partner form """ + _inherit = 'res.partner' + _columns = { + 'issue_ids': fields.one2many('project.issue', 'partner_id', 'Issues'), + 'issue_count': fields.function(_issue_count, string='# Issues', type='integer'), + } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index ace56dd2d5a..a312b8e78d8 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -378,11 +378,14 @@ - + + diff --git a/addons/sale/res_partner_view.xml b/addons/sale/res_partner_view.xml index 5107f0c17af..049d2e40284 100644 --- a/addons/sale/res_partner_view.xml +++ b/addons/sale/res_partner_view.xml @@ -48,10 +48,11 @@ - From abfccd8936da4f228919dcd3f59462c38d9efe41 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Thu, 20 Mar 2014 16:15:42 +0100 Subject: [PATCH 056/423] [WIP] website tour: bootstrap-tour - v0.9.1 bzr revid: chm@openerp.com-20140320151542-blfr1rs1j24xanh8 --- .../lib/bootstrap-tour/bootstrap-tour.css | 44 +- .../lib/bootstrap-tour/bootstrap-tour.js | 1057 ++++++++++------- .../static/src/js/website.tour.banner.js | 3 - addons/website/static/src/js/website.tour.js | 199 ++-- 4 files changed, 755 insertions(+), 548 deletions(-) mode change 100755 => 100644 addons/website/static/lib/bootstrap-tour/bootstrap-tour.css mode change 100755 => 100644 addons/website/static/lib/bootstrap-tour/bootstrap-tour.js diff --git a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css old mode 100755 new mode 100644 index 72c6e8cbab7..5449158e7f4 --- a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css +++ b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css @@ -1,37 +1,59 @@ +/* =========================================================== +# bootstrap-tour - v0.9.1 +# http://bootstraptour.com +# ============================================================== +# Copyright 2012-2013 Ulrich Sossou +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +*/ .tour-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; - z-index: 1009; + z-index: 1100; background-color: #000; opacity: 0.8; } .tour-step-backdrop { position: relative; - z-index: 1011; + z-index: 1101; + background: inherit; } .tour-step-background { position: absolute; - z-index: 1010; - background: #fff; + z-index: 1100; + background: inherit; border-radius: 6px; } +.popover[class*="tour-"] { + z-index: 1100; +} .popover[class*="tour-"] .popover-navigation { padding: 9px 14px; } -.popover[class*="tour-"] .popover-navigation *[data-role=end] { +.popover[class*="tour-"] .popover-navigation *[data-role="end"] { float: right; } -.popover[class*="tour-"] .popover-navigation *[data-role=prev], -.popover[class*="tour-"] .popover-navigation *[data-role=next], -.popover[class*="tour-"] .popover-navigation *[data-role=end] { +.popover[class*="tour-"] .popover-navigation *[data-role="prev"], +.popover[class*="tour-"] .popover-navigation *[data-role="next"], +.popover[class*="tour-"] .popover-navigation *[data-role="end"] { cursor: pointer; } -.popover[class*="tour-"] .popover-navigation *[data-role=prev].disabled, -.popover[class*="tour-"] .popover-navigation *[data-role=next].disabled, -.popover[class*="tour-"] .popover-navigation *[data-role=end].disabled { +.popover[class*="tour-"] .popover-navigation *[data-role="prev"].disabled, +.popover[class*="tour-"] .popover-navigation *[data-role="next"].disabled, +.popover[class*="tour-"] .popover-navigation *[data-role="end"].disabled { cursor: default; } .popover[class*="tour-"].orphan { diff --git a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js old mode 100755 new mode 100644 index 8b45d6da9ee..a0172c718c0 --- a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js +++ b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js @@ -1,5 +1,5 @@ /* =========================================================== -# bootstrap-tour - v0.6.1 +# bootstrap-tour - v0.9.1 # http://bootstraptour.com # ============================================================== # Copyright 2012-2013 Ulrich Sossou @@ -16,220 +16,233 @@ # See the License for the specific language governing permissions and # limitations under the License. */ -(function() { - (function($, window) { - var Tour, document; - document = window.document; - Tour = (function() { - function Tour(options) { - this._options = $.extend({ - name: "tour", - container: "body", - keyboard: true, - storage: window.localStorage, - debug: false, - backdrop: false, - redirect: true, - orphan: false, - basePath: "", - template: "

", - afterSetState: function(key, value) {}, - afterGetState: function(key, value) {}, - afterRemoveState: function(key) {}, - onStart: function(tour) {}, - onEnd: function(tour) {}, - onShow: function(tour) {}, - onShown: function(tour) {}, - onHide: function(tour) {}, - onHidden: function(tour) {}, - onNext: function(tour) {}, - onPrev: function(tour) {} - }, options); - this._steps = []; - this.setCurrentStep(); - this.backdrop = { - overlay: null, - $element: null, - $background: null - }; +(function($, window) { + var Tour, document; + document = window.document; + Tour = (function() { + function Tour(options) { + this._options = $.extend({ + name: "tour", + steps: [], + container: "body", + keyboard: true, + storage: window.localStorage, + debug: false, + backdrop: false, + redirect: true, + orphan: false, + duration: false, + basePath: "", + template: "

", + afterSetState: function(key, value) {}, + afterGetState: function(key, value) {}, + afterRemoveState: function(key) {}, + onStart: function(tour) {}, + onEnd: function(tour) {}, + onShow: function(tour) {}, + onShown: function(tour) {}, + onHide: function(tour) {}, + onHidden: function(tour) {}, + onNext: function(tour) {}, + onPrev: function(tour) {}, + onPause: function(tour, duration) {}, + onResume: function(tour, duration) {} + }, options); + this._force = false; + this._inited = false; + this.backdrop = { + overlay: null, + $element: null, + $background: null, + backgroundShown: false, + overlayElementShown: false + }; + this; + } + + Tour.prototype.addSteps = function(steps) { + var step, _i, _len; + for (_i = 0, _len = steps.length; _i < _len; _i++) { + step = steps[_i]; + this.addStep(step); } + return this; + }; - Tour.prototype.setState = function(key, value) { - var keyName; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - this._options.storage.setItem(keyName, value); - return this._options.afterSetState(keyName, value); - } else { - if (this._state == null) { - this._state = {}; - } - return this._state[key] = value; - } - }; + Tour.prototype.addStep = function(step) { + this._options.steps.push(step); + return this; + }; - Tour.prototype.removeState = function(key) { - var keyName; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - this._options.storage.removeItem(keyName); - return this._options.afterRemoveState(keyName); - } else { - if (this._state != null) { - return delete this._state[key]; - } - } - }; + Tour.prototype.getStep = function(i) { + if (this._options.steps[i] != null) { + return $.extend({ + id: "step-" + i, + path: "", + placement: "right", + title: "", + content: "

", + next: i === this._options.steps.length - 1 ? -1 : i + 1, + prev: i - 1, + animation: true, + container: this._options.container, + backdrop: this._options.backdrop, + redirect: this._options.redirect, + orphan: this._options.orphan, + duration: this._options.duration, + template: this._options.template, + onShow: this._options.onShow, + onShown: this._options.onShown, + onHide: this._options.onHide, + onHidden: this._options.onHidden, + onNext: this._options.onNext, + onPrev: this._options.onPrev, + onPause: this._options.onPause, + onResume: this._options.onResume + }, this._options.steps[i]); + } + }; - Tour.prototype.getState = function(key) { - var keyName, value; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - value = this._options.storage.getItem(keyName); - } else { - if (this._state != null) { - value = this._state[key]; - } - } - if (value === void 0 || value === "null") { - value = null; - } - this._options.afterGetState(key, value); - return value; - }; - - Tour.prototype.addSteps = function(steps) { - var step, _i, _len, _results; - _results = []; - for (_i = 0, _len = steps.length; _i < _len; _i++) { - step = steps[_i]; - _results.push(this.addStep(step)); - } - return _results; - }; - - Tour.prototype.addStep = function(step) { - return this._steps.push(step); - }; - - Tour.prototype.getStep = function(i) { - if (this._steps[i] != null) { - return $.extend({ - id: "step-" + i, - path: "", - placement: "right", - title: "", - content: "

", - next: i === this._steps.length - 1 ? -1 : i + 1, - prev: i - 1, - animation: true, - container: this._options.container, - backdrop: this._options.backdrop, - redirect: this._options.redirect, - orphan: this._options.orphan, - template: this._options.template, - onShow: this._options.onShow, - onShown: this._options.onShown, - onHide: this._options.onHide, - onHidden: this._options.onHidden, - onNext: this._options.onNext, - onPrev: this._options.onPrev - }, this._steps[i]); - } - }; - - Tour.prototype.start = function(force) { - var promise, - _this = this; - if (force == null) { - force = false; - } - if (this.ended() && !force) { - return this._debug("Tour ended, start prevented."); - } - $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=next]").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=next]:not(.disabled)", function(e) { - e.preventDefault(); - return _this.next(); - }); - $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=prev]").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=prev]:not(.disabled)", function(e) { - e.preventDefault(); - return _this.prev(); - }); - $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=end]").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role=end]", function(e) { - e.preventDefault(); - return _this.end(); - }); - this._onResize(function() { + Tour.prototype.init = function(force) { + this._force = force; + if (this.ended()) { + this._debug("Tour ended, init prevented."); + return this; + } + this.setCurrentStep(); + this._initMouseNavigation(); + this._initKeyboardNavigation(); + this._onResize((function(_this) { + return function() { return _this.showStep(_this._current); - }); - this._setupKeyboardNavigation(); + }; + })(this)); + if (this._current !== null) { + this.showStep(this._current); + } + this._inited = true; + return this; + }; + + Tour.prototype.start = function(force) { + var promise; + if (force == null) { + force = false; + } + if (!this._inited) { + this.init(force); + } + if (this._current === null) { promise = this._makePromise(this._options.onStart != null ? this._options.onStart(this) : void 0); - return this._callOnPromiseDone(promise, this.showStep, this._current); - }; + this._callOnPromiseDone(promise, this.showStep, 0); + } + return this; + }; - Tour.prototype.next = function() { - var promise; - if (this.ended()) { - return this._debug("Tour ended, next prevented."); - } - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this._showNextStep); - }; + Tour.prototype.next = function() { + var promise; + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this._showNextStep); + }; - Tour.prototype.prev = function() { - var promise; - if (this.ended()) { - return this._debug("Tour ended, prev prevented."); - } - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this._showPrevStep); - }; + Tour.prototype.prev = function() { + var promise; + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this._showPrevStep); + }; - Tour.prototype.goto = function(i) { - var promise; - if (this.ended()) { - return this._debug("Tour ended, goto prevented."); - } - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this.showStep, i); - }; + Tour.prototype.goTo = function(i) { + var promise; + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this.showStep, i); + }; - Tour.prototype.end = function() { - var endHelper, hidePromise, - _this = this; - endHelper = function(e) { + Tour.prototype.end = function() { + var endHelper, promise; + endHelper = (function(_this) { + return function(e) { $(document).off("click.tour-" + _this._options.name); $(document).off("keyup.tour-" + _this._options.name); $(window).off("resize.tour-" + _this._options.name); - _this.setState("end", "yes"); + _this._setState("end", "yes"); + _this._inited = false; + _this._force = false; + _this._clearTimer(); if (_this._options.onEnd != null) { return _this._options.onEnd(_this); } }; - hidePromise = this.hideStep(this._current); - return this._callOnPromiseDone(hidePromise, endHelper); - }; + })(this); + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, endHelper); + }; - Tour.prototype.ended = function() { - return !!this.getState("end"); - }; + Tour.prototype.ended = function() { + return !this._force && !!this._getState("end"); + }; - Tour.prototype.restart = function() { - this.removeState("current_step"); - this.removeState("end"); - this.setCurrentStep(0); - return this.start(); - }; + Tour.prototype.restart = function() { + this._removeState("current_step"); + this._removeState("end"); + this.setCurrentStep(0); + return this.start(); + }; - Tour.prototype.hideStep = function(i) { - var hideStepHelper, promise, step, - _this = this; - step = this.getStep(i); - promise = this._makePromise(step.onHide != null ? step.onHide(this, i) : void 0); - hideStepHelper = function(e) { + Tour.prototype.pause = function() { + var step; + step = this.getStep(this._current); + if (!(step && step.duration)) { + return this; + } + this._paused = true; + this._duration -= new Date().getTime() - this._start; + window.clearTimeout(this._timer); + this._debug("Paused/Stopped step " + (this._current + 1) + " timer (" + this._duration + " remaining)."); + if (step.onPause != null) { + return step.onPause(this, this._duration); + } + }; + + Tour.prototype.resume = function() { + var step; + step = this.getStep(this._current); + if (!(step && step.duration)) { + return this; + } + this._paused = false; + this._start = new Date().getTime(); + this._duration = this._duration || step.duration; + this._timer = window.setTimeout((function(_this) { + return function() { + if (_this._isLast()) { + return _this.next(); + } else { + return _this.end(); + } + }; + })(this), this._duration); + this._debug("Started step " + (this._current + 1) + " timer with duration " + this._duration); + if ((step.onResume != null) && this._duration !== step.duration) { + return step.onResume(this, this._duration); + } + }; + + Tour.prototype.hideStep = function(i) { + var hideStepHelper, promise, step; + step = this.getStep(i); + if (!step) { + return; + } + this._clearTimer(); + promise = this._makePromise(step.onHide != null ? step.onHide(this, i) : void 0); + hideStepHelper = (function(_this) { + return function(e) { var $element; - $element = _this._isOrphan(step) ? $("body") : $(step.element); - $element.popover("destroy"); + $element = $(step.element); + if (!($element.data("bs.popover") || $element.data("popover"))) { + $element = $("body"); + } + $element.popover("destroy").removeClass("tour-" + _this._options.name + "-element tour-" + _this._options.name + "-" + i + "-element"); if (step.reflex) { $element.css("cursor", "").off("click.tour-" + _this._options.name); } @@ -240,23 +253,37 @@ return step.onHidden(_this); } }; - this._callOnPromiseDone(promise, hideStepHelper); - return promise; - }; + })(this); + this._callOnPromiseDone(promise, hideStepHelper); + return promise; + }; - Tour.prototype.showStep = function(i) { - var promise, showStepHelper, skipToPrevious, step, - _this = this; - step = this.getStep(i); - if (!step) { - return; - } - skipToPrevious = i < this._current; - promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0); - showStepHelper = function(e) { + Tour.prototype.showStep = function(i) { + var promise, showStepHelper, skipToPrevious, step; + if (this.ended()) { + this._debug("Tour ended, showStep prevented."); + return this; + } + step = this.getStep(i); + if (!step) { + return; + } + skipToPrevious = i < this._current; + promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0); + showStepHelper = (function(_this) { + return function(e) { var current_path, path; _this.setCurrentStep(i); - path = $.isFunction(step.path) ? step.path.call() : _this._options.basePath + step.path; + path = (function() { + switch ({}.toString.call(step.path)) { + case "[object Function]": + return step.path(); + case "[object String]": + return this._options.basePath + step.path; + default: + return step.path; + } + }).call(_this); current_path = [document.location.pathname, document.location.hash].join(""); if (_this._isRedirect(path, current_path)) { _this._redirect(step, path); @@ -277,283 +304,413 @@ if (step.backdrop) { _this._showBackdrop(!_this._isOrphan(step) ? step.element : void 0); } - _this._showPopover(step, i); - if (step.onShown != null) { - step.onShown(_this); + _this._scrollIntoView(step.element, function() { + if ((step.element != null) && step.backdrop) { + _this._showOverlayElement(step.element); + } + _this._showPopover(step, i); + if (step.onShown != null) { + step.onShown(_this); + } + return _this._debug("Step " + (_this._current + 1) + " of " + _this._options.steps.length); + }); + if (step.duration) { + return _this.resume(); } - return _this._debug("Step " + (_this._current + 1) + " of " + _this._steps.length); }; - return this._callOnPromiseDone(promise, showStepHelper); - }; + })(this); + this._callOnPromiseDone(promise, showStepHelper); + return promise; + }; - Tour.prototype.setCurrentStep = function(value) { - if (value != null) { - this._current = value; - return this.setState("current_step", value); - } else { - this._current = this.getState("current_step"); - return this._current = this._current === null ? 0 : parseInt(this._current, 10); + Tour.prototype.getCurrentStep = function() { + return this._current; + }; + + Tour.prototype.setCurrentStep = function(value) { + if (value != null) { + this._current = value; + this._setState("current_step", value); + } else { + this._current = this._getState("current_step"); + this._current = this._current === null ? null : parseInt(this._current, 10); + } + return this; + }; + + Tour.prototype._setState = function(key, value) { + var e, keyName; + if (this._options.storage) { + keyName = "" + this._options.name + "_" + key; + try { + this._options.storage.setItem(keyName, value); + } catch (_error) { + e = _error; + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + this.debug("LocalStorage quota exceeded. State storage failed."); + } } - }; + return this._options.afterSetState(keyName, value); + } else { + if (this._state == null) { + this._state = {}; + } + return this._state[key] = value; + } + }; - Tour.prototype._showNextStep = function() { - var promise, showNextStepHelper, step, - _this = this; - step = this.getStep(this._current); - showNextStepHelper = function(e) { + Tour.prototype._removeState = function(key) { + var keyName; + if (this._options.storage) { + keyName = "" + this._options.name + "_" + key; + this._options.storage.removeItem(keyName); + return this._options.afterRemoveState(keyName); + } else { + if (this._state != null) { + return delete this._state[key]; + } + } + }; + + Tour.prototype._getState = function(key) { + var keyName, value; + if (this._options.storage) { + keyName = "" + this._options.name + "_" + key; + value = this._options.storage.getItem(keyName); + } else { + if (this._state != null) { + value = this._state[key]; + } + } + if (value === void 0 || value === "null") { + value = null; + } + this._options.afterGetState(key, value); + return value; + }; + + Tour.prototype._showNextStep = function() { + var promise, showNextStepHelper, step; + step = this.getStep(this._current); + showNextStepHelper = (function(_this) { + return function(e) { return _this.showStep(step.next); }; - promise = this._makePromise((step.onNext != null ? step.onNext(this) : void 0)); - return this._callOnPromiseDone(promise, showNextStepHelper); - }; + })(this); + promise = this._makePromise(step.onNext != null ? step.onNext(this) : void 0); + return this._callOnPromiseDone(promise, showNextStepHelper); + }; - Tour.prototype._showPrevStep = function() { - var promise, showPrevStepHelper, step, - _this = this; - step = this.getStep(this._current); - showPrevStepHelper = function(e) { + Tour.prototype._showPrevStep = function() { + var promise, showPrevStepHelper, step; + step = this.getStep(this._current); + showPrevStepHelper = (function(_this) { + return function(e) { return _this.showStep(step.prev); }; - promise = this._makePromise((step.onPrev != null ? step.onPrev(this) : void 0)); - return this._callOnPromiseDone(promise, showPrevStepHelper); - }; + })(this); + promise = this._makePromise(step.onPrev != null ? step.onPrev(this) : void 0); + return this._callOnPromiseDone(promise, showPrevStepHelper); + }; - Tour.prototype._debug = function(text) { - if (this._options.debug) { - return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + text); - } - }; + Tour.prototype._debug = function(text) { + if (this._options.debug) { + return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + text); + } + }; - Tour.prototype._isRedirect = function(path, currentPath) { - return (path != null) && path !== "" && path.replace(/\?.*$/, "").replace(/\/?$/, "") !== currentPath.replace(/\/?$/, ""); - }; + Tour.prototype._isRedirect = function(path, currentPath) { + return (path != null) && path !== "" && ((toString.call(path) === "[object RegExp]" && !path.test(currentPath)) || (toString.call(path) === "[object String]" && path.replace(/\?.*$/, "").replace(/\/?$/, "") !== currentPath.replace(/\/?$/, ""))); + }; - Tour.prototype._redirect = function(step, path) { - if ($.isFunction(step.redirect)) { - return step.redirect.call(this, path); - } else if (step.redirect === true) { - this._debug("Redirect to " + path); - return document.location.href = path; - } - }; + Tour.prototype._redirect = function(step, path) { + if ($.isFunction(step.redirect)) { + return step.redirect.call(this, path); + } else if (step.redirect === true) { + this._debug("Redirect to " + path); + return document.location.href = path; + } + }; - Tour.prototype._isOrphan = function(step) { - return (step.element == null) || !$(step.element).length || $(step.element).is(":hidden"); - }; + Tour.prototype._isOrphan = function(step) { + return (step.element == null) || !$(step.element).length || $(step.element).is(":hidden") && ($(step.element)[0].namespaceURI !== "http://www.w3.org/2000/svg"); + }; - Tour.prototype._showPopover = function(step, i) { - var $element, $navigation, $template, $tip, isOrphan, options, - _this = this; - options = $.extend({}, this._options); - $template = $.isFunction(step.template) ? $(step.template(i, step)) : $(step.template); - $navigation = $template.find(".popover-navigation"); - isOrphan = this._isOrphan(step); - if (isOrphan) { - step.element = "body"; - step.placement = "top"; - $template = $template.addClass("orphan"); - } - $element = $(step.element); - $template.addClass("tour-" + this._options.name); - if (step.options) { - $.extend(options, step.options); - } - if (step.reflex) { - $element.css("cursor", "pointer").on("click.tour-" + this._options.name, function(e) { - if (_this._current < _this._steps.length - 1) { + Tour.prototype._isLast = function() { + return this._current < this._options.steps.length - 1; + }; + + Tour.prototype._showPopover = function(step, i) { + var $element, $navigation, $template, $tip, isOrphan, options; + options = $.extend({}, this._options); + $template = $.isFunction(step.template) ? $(step.template(i, step)) : $(step.template); + $navigation = $template.find(".popover-navigation"); + isOrphan = this._isOrphan(step); + if (isOrphan) { + step.element = "body>*:last"; + step.placement = "top"; + $template = $template.addClass("orphan"); + } + $element = $(step.element); + $template.addClass("tour-" + this._options.name + " tour-" + this._options.name + "-" + i); + $element.addClass("tour-" + this._options.name + "-element tour-" + this._options.name + "-" + i + "-element"); + if (step.options) { + $.extend(options, step.options); + } + if (step.reflex) { + $element.css("cursor", "pointer").on("click.tour-" + this._options.name, (function(_this) { + return function() { + if (_this._isLast()) { return _this.next(); } else { return _this.end(); } - }); - } - if (step.prev < 0) { - $navigation.find("*[data-role=prev]").addClass("disabled"); - } - if (step.next < 0) { - $navigation.find("*[data-role=next]").addClass("disabled"); - } - step.template = $template.clone().wrap("
").parent().html(); - $element.popover({ - placement: step.placement, - trigger: "manual", - title: step.title, - content: step.content, - html: true, - animation: step.animation, - container: step.container, - template: step.template, - selector: step.element - }).popover("show"); - $tip = $element.data("bs.popover") ? $element.data("bs.popover").tip() : $element.data("popover").tip(); - $tip.attr("id", step.id); - this._scrollIntoView($tip); - this._reposition($tip, step); - if (isOrphan) { - return this._center($tip); - } - }; + }; + })(this)); + } + if (step.prev < 0) { + $navigation.find("[data-role='prev']").addClass("disabled"); + } + if (step.next < 0) { + $navigation.find("[data-role='next']").addClass("disabled"); + } + if (!step.duration) { + $navigation.find("[data-role='pause-resume']").remove(); + } + step.template = $template.clone().wrap("
").parent().html(); + $element.popover({ + placement: step.placement, + trigger: "manual", + title: step.title, + content: step.content, + html: true, + animation: step.animation, + container: step.container, + template: step.template, + selector: step.element + }).popover("show"); + $tip = $element.data("bs.popover") ? $element.data("bs.popover").tip() : $element.data("popover").tip(); + $tip.attr("id", step.id); + this._reposition($tip, step); + if (isOrphan) { + return this._center($tip); + } + }; - Tour.prototype._reposition = function($tip, step) { - var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; - offsetWidth = $tip[0].offsetWidth; - offsetHeight = $tip[0].offsetHeight; - tipOffset = $tip.offset(); - originalLeft = tipOffset.left; - originalTop = tipOffset.top; - offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); - if (offsetBottom < 0) { - tipOffset.top = tipOffset.top + offsetBottom; + Tour.prototype._reposition = function($tip, step) { + var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; + offsetWidth = $tip[0].offsetWidth; + offsetHeight = $tip[0].offsetHeight; + tipOffset = $tip.offset(); + originalLeft = tipOffset.left; + originalTop = tipOffset.top; + offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); + if (offsetBottom < 0) { + tipOffset.top = tipOffset.top + offsetBottom; + } + offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); + if (offsetRight < 0) { + tipOffset.left = tipOffset.left + offsetRight; + } + if (tipOffset.top < 0) { + tipOffset.top = 0; + } + if (tipOffset.left < 0) { + tipOffset.left = 0; + } + $tip.offset(tipOffset); + if (step.placement === "bottom" || step.placement === "top") { + if (originalLeft !== tipOffset.left) { + return this._replaceArrow($tip, (tipOffset.left - originalLeft) * 2, offsetWidth, "left"); } - offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); - if (offsetRight < 0) { - tipOffset.left = tipOffset.left + offsetRight; + } else { + if (originalTop !== tipOffset.top) { + return this._replaceArrow($tip, (tipOffset.top - originalTop) * 2, offsetHeight, "top"); } - if (tipOffset.top < 0) { - tipOffset.top = 0; - } - if (tipOffset.left < 0) { - tipOffset.left = 0; - } - $tip.offset(tipOffset); - if (step.placement === "bottom" || step.placement === "top") { - if (originalLeft !== tipOffset.left) { - return this._replaceArrow($tip, (tipOffset.left - originalLeft) * 2, offsetWidth, "left"); + } + }; + + Tour.prototype._center = function($tip) { + return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); + }; + + Tour.prototype._replaceArrow = function($tip, delta, dimension, position) { + return $tip.find(".arrow").css(position, delta ? 50 * (1 - delta / dimension) + "%" : ""); + }; + + Tour.prototype._scrollIntoView = function(element, callback) { + var $element, $window, counter, offsetTop, scrollTop, windowHeight; + $element = $(element); + if (!$element.length) { + return callback(); + } + $window = $(window); + offsetTop = $element.offset().top; + windowHeight = $window.height(); + scrollTop = Math.max(0, offsetTop - (windowHeight / 2)); + this._debug("Scroll into view. ScrollTop: " + scrollTop + ". Element offset: " + offsetTop + ". Window height: " + windowHeight + "."); + counter = 0; + return $("body,html").stop(true, true).animate({ + scrollTop: Math.ceil(scrollTop) + }, (function(_this) { + return function() { + if (++counter === 2) { + callback(); + return _this._debug("Scroll into view. Animation end element offset: " + ($element.offset().top) + ". Window height: " + ($window.height()) + "."); } + }; + })(this)); + }; + + Tour.prototype._onResize = function(callback, timeout) { + return $(window).on("resize.tour-" + this._options.name, function() { + clearTimeout(timeout); + return timeout = setTimeout(callback, 100); + }); + }; + + Tour.prototype._initMouseNavigation = function() { + var _this; + _this = this; + return $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']:not(.disabled)").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']:not(.disabled)").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']:not(.disabled)", (function(_this) { + return function(e) { + e.preventDefault(); + return _this.next(); + }; + })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']:not(.disabled)", (function(_this) { + return function(e) { + e.preventDefault(); + return _this.prev(); + }; + })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']", (function(_this) { + return function(e) { + e.preventDefault(); + return _this.end(); + }; + })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']", function(e) { + var $this; + e.preventDefault(); + $this = $(this); + $this.text(_this._paused ? $this.data("pause-text") : $this.data("resume-text")); + if (_this._paused) { + return _this.resume(); } else { - if (originalTop !== tipOffset.top) { - return this._replaceArrow($tip, (tipOffset.top - originalTop) * 2, offsetHeight, "top"); - } + return _this.pause(); } - }; + }); + }; - Tour.prototype._center = function($tip) { - return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); - }; - - Tour.prototype._replaceArrow = function($tip, delta, dimension, position) { - return $tip.find(".arrow").css(position, delta ? 50 * (1 - delta / dimension) + "%" : ""); - }; - - Tour.prototype._scrollIntoView = function(tip) { - return $("html, body").stop().animate({ - scrollTop: Math.ceil(tip.offset().top - ($(window).height() / 2)) - }); - }; - - Tour.prototype._onResize = function(callback, timeout) { - return $(window).on("resize.tour-" + this._options.name, function() { - clearTimeout(timeout); - return timeout = setTimeout(callback, 100); - }); - }; - - Tour.prototype._setupKeyboardNavigation = function() { - var _this = this; - if (this._options.keyboard) { - return $(document).on("keyup.tour-" + this._options.name, function(e) { - if (!e.which) { - return; - } - switch (e.which) { - case 39: - e.preventDefault(); - if (_this._current < _this._steps.length - 1) { - return _this.next(); - } else { - return _this.end(); - } - break; - case 37: - e.preventDefault(); - if (_this._current > 0) { - return _this.prev(); - } - break; - case 27: - e.preventDefault(); + Tour.prototype._initKeyboardNavigation = function() { + if (!this._options.keyboard) { + return; + } + return $(document).on("keyup.tour-" + this._options.name, (function(_this) { + return function(e) { + if (!e.which) { + return; + } + switch (e.which) { + case 39: + e.preventDefault(); + if (_this._isLast()) { + return _this.next(); + } else { return _this.end(); - } - }); - } - }; + } + break; + case 37: + e.preventDefault(); + if (_this._current > 0) { + return _this.prev(); + } + break; + case 27: + e.preventDefault(); + return _this.end(); + } + }; + })(this)); + }; - Tour.prototype._makePromise = function(result) { - if (result && $.isFunction(result.then)) { - return result; - } else { - return null; - } - }; + Tour.prototype._makePromise = function(result) { + if (result && $.isFunction(result.then)) { + return result; + } else { + return null; + } + }; - Tour.prototype._callOnPromiseDone = function(promise, cb, arg) { - var _this = this; - if (promise) { - return promise.then(function(e) { + Tour.prototype._callOnPromiseDone = function(promise, cb, arg) { + if (promise) { + return promise.then((function(_this) { + return function(e) { return cb.call(_this, arg); - }); - } else { - return cb.call(this, arg); - } - }; + }; + })(this)); + } else { + return cb.call(this, arg); + } + }; - Tour.prototype._showBackdrop = function(element) { - if (this.backdrop.overlay !== null) { - return; - } - this._showOverlay(); - if (element != null) { - return this._showOverlayElement(element); - } - }; + Tour.prototype._showBackdrop = function(element) { + if (this.backdrop.backgroundShown) { + return; + } + this.backdrop = $("
", { + "class": "tour-backdrop" + }); + this.backdrop.backgroundShown = true; + return $("body").append(this.backdrop); + }; - Tour.prototype._hideBackdrop = function() { - if (this.backdrop.overlay === null) { - return; - } - if (this.backdrop.$element) { - this._hideOverlayElement(); - } - return this._hideOverlay(); - }; + Tour.prototype._hideBackdrop = function() { + this._hideOverlayElement(); + return this._hideBackground(); + }; - Tour.prototype._showOverlay = function() { - this.backdrop = $("
", { - "class": "tour-backdrop" - }); - return $("body").append(this.backdrop); - }; + Tour.prototype._hideBackground = function() { + this.backdrop.remove(); + this.backdrop.overlay = null; + return this.backdrop.backgroundShown = false; + }; - Tour.prototype._hideOverlay = function() { - this.backdrop.remove(); - return this.backdrop.overlay = null; - }; + Tour.prototype._showOverlayElement = function(element) { + var $background, $element, offset; + $element = $(element); + if (!$element || $element.length === 0 || this.backdrop.overlayElementShown) { + return; + } + this.backdrop.overlayElementShown = true; + $background = $("
"); + offset = $element.offset(); + offset.top = offset.top; + offset.left = offset.left; + $background.width($element.innerWidth()).height($element.innerHeight()).addClass("tour-step-background").offset(offset); + $element.addClass("tour-step-backdrop"); + $("body").append($background); + this.backdrop.$element = $element; + return this.backdrop.$background = $background; + }; - Tour.prototype._showOverlayElement = function(element) { - var $background, $element, offset; - $element = $(element); - $background = $("
"); - offset = $element.offset(); - offset.top = offset.top; - offset.left = offset.left; - $background.width($element.innerWidth()).height($element.innerHeight()).addClass("tour-step-background").offset(offset); - $element.addClass("tour-step-backdrop"); - $("body").append($background); - this.backdrop.$element = $element; - return this.backdrop.$background = $background; - }; + Tour.prototype._hideOverlayElement = function() { + if (!this.backdrop.overlayElementShown) { + return; + } + this.backdrop.$element.removeClass("tour-step-backdrop"); + this.backdrop.$background.remove(); + this.backdrop.$element = null; + this.backdrop.$background = null; + return this.backdrop.overlayElementShown = false; + }; - Tour.prototype._hideOverlayElement = function() { - this.backdrop.$element.removeClass("tour-step-backdrop"); - this.backdrop.$background.remove(); - this.backdrop.$element = null; - return this.backdrop.$background = null; - }; + Tour.prototype._clearTimer = function() { + window.clearTimeout(this._timer); + this._timer = null; + return this._duration = null; + }; - return Tour; + return Tour; - })(); - return window.Tour = Tour; - })(jQuery, window); - -}).call(this); + })(); + return window.Tour = Tour; +})(jQuery, window); diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 65099d03986..443405e2401 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -15,7 +15,6 @@ popover: { next: _t("Start Tutorial"), end: _t("Skip It") }, }, { - waitNot: '.popover.tour', element: 'button[data-action=edit]', placement: 'bottom', title: _t("Edit this page"), @@ -52,7 +51,6 @@ popover: { next: _t("Continue") }, }, { - waitNot: '.popover.tour', element: 'button[data-action=snippet]', placement: 'bottom', title: _t("Add Another Block"), @@ -81,7 +79,6 @@ popover: { next: _t("Continue") }, }, { - waitNot: '.popover.tour', element: 'a[data-action=show-mobile-preview]', placement: 'bottom', title: _t("Test Your Mobile Version"), diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index fc0dd513cf2..df6108e0278 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -32,7 +32,7 @@ if (website.EditorBar) { var self = this; var menu = $('#help-menu'); _.each(website.Tour.tours, function (tour) { - if (tour.mode != "tutorial") { + if (tour.mode === "test") { return; } var $menuItem = $($.parseHTML('
  • '+tour.name+'
  • ')); @@ -90,16 +90,19 @@ website.Tour = {}; website.Tour.tours = {}; website.Tour.state = null; website.Tour.register = function (tour) { + if (tour.mode !== "test") tour.mode = "tutorial"; website.Tour.tours[tour.id] = tour; }; website.Tour.run = function (tour_id, mode) { - if (localStorage.getItem("tour")) { // only one test running + if (localStorage.getItem("tour") && mode === "test") { // only one test running return; } var tour = website.Tour.tours[tour_id]; - website.Tour.save_state(tour.id, mode || tour.mode, 0); - if (tour.path) { + website.Tour.saveState(tour.id, mode || tour.mode, 0); + if (tour.path && !window.location.href.match(new RegExp("("+website.Tour.getLang()+")?"+tour.path+"#?$", "i"))) { window.location.href = "/"+website.Tour.getLang()+tour.path; + } else { + website.Tour.running(); } }; website.Tour.registerSteps = function (tour) { @@ -114,48 +117,82 @@ website.Tour.registerSteps = function (tour) { if (!step.waitNot && index > 0 && tour.steps[index-1] && tour.steps[index-1].popover && tour.steps[index-1].popover.next) { - step.waitNot = '.popover.tour:visible'; + step.waitNot = '.popover.tour.fade.in:visible'; } if (!step.waitFor && index > 0 && tour.steps[index-1].snippet) { step.waitFor = '.oe_overlay_options .oe_options:visible'; } - if (!step.element) step.orphan = true; - - var snippet = step.element.match(/#oe_snippets (.*) \.oe_snippet_thumbnail/); + var snippet = step.element && step.element.match(/#oe_snippets (.*) \.oe_snippet_thumbnail/); if (snippet) { step.snippet = snippet[1]; } else if (step.snippet) { step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail'; } + + if (!step.element) step.orphan = true; } if (tour.steps[index-1] && tour.steps[index-1].popover && tour.steps[index-1].popover.next) { var step = { - step_id: index, - waitNot: '.popover.tour:visible' + id: index, + waitNot: '.popover.tour.fade.in:visible' }; tour.steps.push(step); } // rendering bootstrap tour and popover - if (tour.mode != "test" || typeof Tour !== "undefined") { + if (tour.mode !== "test" || typeof Tour !== "undefined") { tour.tour = new Tour({ - name: this.id, + debug: true, + name: tour.id, storage: localStorage, keyboard: false, - template: this.popover(), + template: website.Tour.popover(), onHide: function () { window.scrollTo(0, 0); } }); + for (var index=0, len=tour.steps.length; index -1) { - tour_id = window.location.href.match(/#tutorial\.(.*)=true/)[1]; - mode = "tutorial"; - step_id = 0; +website.Tour.getState = function () { + var state = JSON.parse(localStorage.getItem("tour") || 'false') || {}; + var tour_id,mode,step_id; + if (!state.id && window.location.href.indexOf("#tutorial.") > -1) { + state = { + "id": window.location.href.match(/#tutorial\.(.*)=true/)[1], + "mode": "tutorial", + "step_id": 0 + }; } - if (!tour_id) { + if (!state.id) { return; } - var tour = website.Tour.tours[tour_id]; - return {'tour': tour, 'tour_id': tour_id, 'mode': mode, 'step_id': step_id}; + state.tour = website.Tour.tours[state.id]; + state.step = state.tour.steps[state.step_id]; + return state; }; website.Tour.error = function (tour, step, message) { website.Tour.reset(); throw new Error(message + - + "\ntour:" + tour.id + - + "\nstep:" + step.id + ": '" + (step._title || step.title) + "'" + + "\ntour: " + tour.id + + + "\nstep: " + step.id + ": '" + (step._title || step.title) + "'" + '\nhref: ' + window.location.href + '\nreferrer: ' + document.referrer + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) + '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) + '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) - + "\nlocalStorage: " + localStorage.getItem("tour") + + "\nlocalStorage: " + JSON.stringify(localStorage) + '\n\n' + $("body").html() ); }; @@ -206,24 +242,39 @@ website.Tour.lists = function () { } return tour_ids; }; -website.Tour.save_state = function (tour_id, mode, step_id) { - localStorage.setItem("tour", '{tour_id:'+tour_id+', mode:'+mode+', step_id:'+step_id+'}'); +website.Tour.saveState = function (tour_id, mode, step_id) { + localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id})); }; website.Tour.reset = function () { - var running = website.Tour.get_state(); - for (var k in running.tour.steps) { - running.tour.steps[k].busy = false; + var state = website.Tour.getState(); + if (state) { + for (var k in state.tour.steps) { + state.tour.steps[k].busy = false; + } + if (state.tour.tour) { + state.tour.tour.end(); + } } localStorage.removeItem("tour"); clearTimeout(website.Tour.timer); clearTimeout(website.Tour.testtimer); - $('.popover.tour').remove(); + $(".popover.tour").remove(); }; website.Tour.running = function () { - var running = website.Tour.get_state(); - website.Tour.registerSteps(running.tour); - website.Tour.nextStep( running.tour, running.step_id ); + var state = website.Tour.getState(); + if (state) { + website.Tour.registerSteps(state.tour); + if ($.ajaxBusy) { + $(document).ajaxStop(function() { + setTimeout(function () { + website.Tour.nextStep( state.tour, state.step, state.mode === "test" ? 5000 : 0 ); + },0); + }); + } else { + website.Tour.nextStep( state.tour, state.step, state.mode === "test" ? 5000 : 0 ); + } + } }; website.Tour.timer = null; @@ -238,83 +289,62 @@ website.Tour.check = function (step) { website.Tour.waitNextStep = function (tour, step, overlaps) { var time = new Date().getTime(); var timer; + var next = tour.steps[step.id+1]; window.onbeforeunload = function () { clearTimeout(website.Tour.timer); clearTimeout(website.Tour.testtimer); }; - // check popover activity - $(".popover.tour button") - .off() - .on("click", function () { - $(".popover.tour").remove(); - if (step.busy) return; - if (!$(this).is("[data-role='next']")) { - clearTimeout(website.Tour.timer); - step.busy = true; - if (tour.tour) { - tour.tour.end(); - } - tour.endTour(tour); - } - }); - function checkNext () { + website.Tour.autoToggleBootstrapTour(); + clearTimeout(website.Tour.timer); - if (step.busy) return; - if (website.Tour.check(step)) { - step.busy = true; + if (next.busy) return; + if (website.Tour.check(next)) { + next.busy = true; + clearTimeout(website.Tour.currentTimer); // use an other timeout for cke dom loading setTimeout(function () { - website.Tour.nextStep(tour, step, overlaps); + website.Tour.nextStep(tour, next, overlaps); }, website.Tour.defaultDelay); } else if (!overlaps || new Date().getTime() - time < overlaps) { - if (self.current.element) { - var $popover = $(".popover.tour"); - if(!$(self.current.element).is(":visible")) { - $popover.data("hide", true).fadeOut(300); - } else if($popover.data("hide")) { - $popover.data("hide", false).fadeIn(150); - } - } website.Tour.timer = setTimeout(checkNext, website.Tour.defaultDelay); } else { - website.Tour.error(tour, step, "Can't arrive to the next step"); + website.Tour.error(tour, next, "Can't arrive to the next step"); } } checkNext(); }; +website.Tour.currentTimer = null; website.Tour.nextStep = function (tour, step, overlaps) { - var state = website.Tour.get_state(); - website.Tour.save_state(tour.id, state.mode, step.id); + var state = website.Tour.getState(); + website.Tour.saveState(state.id, state.mode, step.id); - // clear popover (fix for boostrap tour if the element is removed before destroy popover) - $(".popover.tour").remove(); - // go to step in bootstrap tour - if (tour.tour) { - tour.tour.goto(step.id); + website.Tour.autoToggleBootstrapTour(); + + if (step.onload) { + step.onload(); } - step.onload(); var next = tour.steps[step.id+1]; if (next) { setTimeout(function () { - website.Tour.waitNextStep(tour, next, overlaps); + website.Tour.waitNextStep(tour, step, overlaps); if (state.mode === "test") { setTimeout(function(){ website.Tour.autoNextStep(tour, step); }, website.Tour.defaultDelay); } - }, next && next.wait || 0); + }, next.wait || 0); } else { website.Tour.endTour(tour); } }; website.Tour.endTour = function (tour) { - var state = website.Tour.get_state(); - var test = state.step_id >= tour.steps.length-1; - this.reset(); + var state = website.Tour.getState(); + var test = state.step.id >= state.tour.steps.length-1; + website.Tour.reset(); if (test) { console.log('ok'); } else { @@ -388,7 +418,8 @@ website.Tour.autoDragAndDropSnippet = function (selector) { $dropZone.trigger($.Event("mouseup", { which: 1, pageX: dropPosition.left, pageY: dropPosition.top })); }; -website.ready(website.Tour.running); +//$(document).ready(website.Tour.running); +website.ready().then(website.Tour.running); }()); From 58b6aeb01d489922f8311e6a390805d9cb1c877f Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 12:07:50 +0100 Subject: [PATCH 057/423] [IMP] website tour: remove bootstrap Tour lib bzr revid: chm@openerp.com-20140321110750-ew8rj3nv2jcort1x --- .../lib/bootstrap-tour/bootstrap-tour.css | 65 -- .../lib/bootstrap-tour/bootstrap-tour.js | 716 ------------------ addons/website/static/src/css/editor.css | 24 +- addons/website/static/src/css/editor.sass | 19 +- .../static/src/js/website.tour.banner.js | 2 + addons/website/static/src/js/website.tour.js | 349 +++++---- 6 files changed, 258 insertions(+), 917 deletions(-) delete mode 100644 addons/website/static/lib/bootstrap-tour/bootstrap-tour.css delete mode 100644 addons/website/static/lib/bootstrap-tour/bootstrap-tour.js diff --git a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css deleted file mode 100644 index 5449158e7f4..00000000000 --- a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.css +++ /dev/null @@ -1,65 +0,0 @@ -/* =========================================================== -# bootstrap-tour - v0.9.1 -# http://bootstraptour.com -# ============================================================== -# Copyright 2012-2013 Ulrich Sossou -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -*/ -.tour-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1100; - background-color: #000; - opacity: 0.8; -} -.tour-step-backdrop { - position: relative; - z-index: 1101; - background: inherit; -} -.tour-step-background { - position: absolute; - z-index: 1100; - background: inherit; - border-radius: 6px; -} -.popover[class*="tour-"] { - z-index: 1100; -} -.popover[class*="tour-"] .popover-navigation { - padding: 9px 14px; -} -.popover[class*="tour-"] .popover-navigation *[data-role="end"] { - float: right; -} -.popover[class*="tour-"] .popover-navigation *[data-role="prev"], -.popover[class*="tour-"] .popover-navigation *[data-role="next"], -.popover[class*="tour-"] .popover-navigation *[data-role="end"] { - cursor: pointer; -} -.popover[class*="tour-"] .popover-navigation *[data-role="prev"].disabled, -.popover[class*="tour-"] .popover-navigation *[data-role="next"].disabled, -.popover[class*="tour-"] .popover-navigation *[data-role="end"].disabled { - cursor: default; -} -.popover[class*="tour-"].orphan { - position: fixed; - margin-top: 0; -} -.popover[class*="tour-"].orphan .arrow { - display: none; -} diff --git a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js b/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js deleted file mode 100644 index a0172c718c0..00000000000 --- a/addons/website/static/lib/bootstrap-tour/bootstrap-tour.js +++ /dev/null @@ -1,716 +0,0 @@ -/* =========================================================== -# bootstrap-tour - v0.9.1 -# http://bootstraptour.com -# ============================================================== -# Copyright 2012-2013 Ulrich Sossou -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -*/ -(function($, window) { - var Tour, document; - document = window.document; - Tour = (function() { - function Tour(options) { - this._options = $.extend({ - name: "tour", - steps: [], - container: "body", - keyboard: true, - storage: window.localStorage, - debug: false, - backdrop: false, - redirect: true, - orphan: false, - duration: false, - basePath: "", - template: "

    ", - afterSetState: function(key, value) {}, - afterGetState: function(key, value) {}, - afterRemoveState: function(key) {}, - onStart: function(tour) {}, - onEnd: function(tour) {}, - onShow: function(tour) {}, - onShown: function(tour) {}, - onHide: function(tour) {}, - onHidden: function(tour) {}, - onNext: function(tour) {}, - onPrev: function(tour) {}, - onPause: function(tour, duration) {}, - onResume: function(tour, duration) {} - }, options); - this._force = false; - this._inited = false; - this.backdrop = { - overlay: null, - $element: null, - $background: null, - backgroundShown: false, - overlayElementShown: false - }; - this; - } - - Tour.prototype.addSteps = function(steps) { - var step, _i, _len; - for (_i = 0, _len = steps.length; _i < _len; _i++) { - step = steps[_i]; - this.addStep(step); - } - return this; - }; - - Tour.prototype.addStep = function(step) { - this._options.steps.push(step); - return this; - }; - - Tour.prototype.getStep = function(i) { - if (this._options.steps[i] != null) { - return $.extend({ - id: "step-" + i, - path: "", - placement: "right", - title: "", - content: "

    ", - next: i === this._options.steps.length - 1 ? -1 : i + 1, - prev: i - 1, - animation: true, - container: this._options.container, - backdrop: this._options.backdrop, - redirect: this._options.redirect, - orphan: this._options.orphan, - duration: this._options.duration, - template: this._options.template, - onShow: this._options.onShow, - onShown: this._options.onShown, - onHide: this._options.onHide, - onHidden: this._options.onHidden, - onNext: this._options.onNext, - onPrev: this._options.onPrev, - onPause: this._options.onPause, - onResume: this._options.onResume - }, this._options.steps[i]); - } - }; - - Tour.prototype.init = function(force) { - this._force = force; - if (this.ended()) { - this._debug("Tour ended, init prevented."); - return this; - } - this.setCurrentStep(); - this._initMouseNavigation(); - this._initKeyboardNavigation(); - this._onResize((function(_this) { - return function() { - return _this.showStep(_this._current); - }; - })(this)); - if (this._current !== null) { - this.showStep(this._current); - } - this._inited = true; - return this; - }; - - Tour.prototype.start = function(force) { - var promise; - if (force == null) { - force = false; - } - if (!this._inited) { - this.init(force); - } - if (this._current === null) { - promise = this._makePromise(this._options.onStart != null ? this._options.onStart(this) : void 0); - this._callOnPromiseDone(promise, this.showStep, 0); - } - return this; - }; - - Tour.prototype.next = function() { - var promise; - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this._showNextStep); - }; - - Tour.prototype.prev = function() { - var promise; - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this._showPrevStep); - }; - - Tour.prototype.goTo = function(i) { - var promise; - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, this.showStep, i); - }; - - Tour.prototype.end = function() { - var endHelper, promise; - endHelper = (function(_this) { - return function(e) { - $(document).off("click.tour-" + _this._options.name); - $(document).off("keyup.tour-" + _this._options.name); - $(window).off("resize.tour-" + _this._options.name); - _this._setState("end", "yes"); - _this._inited = false; - _this._force = false; - _this._clearTimer(); - if (_this._options.onEnd != null) { - return _this._options.onEnd(_this); - } - }; - })(this); - promise = this.hideStep(this._current); - return this._callOnPromiseDone(promise, endHelper); - }; - - Tour.prototype.ended = function() { - return !this._force && !!this._getState("end"); - }; - - Tour.prototype.restart = function() { - this._removeState("current_step"); - this._removeState("end"); - this.setCurrentStep(0); - return this.start(); - }; - - Tour.prototype.pause = function() { - var step; - step = this.getStep(this._current); - if (!(step && step.duration)) { - return this; - } - this._paused = true; - this._duration -= new Date().getTime() - this._start; - window.clearTimeout(this._timer); - this._debug("Paused/Stopped step " + (this._current + 1) + " timer (" + this._duration + " remaining)."); - if (step.onPause != null) { - return step.onPause(this, this._duration); - } - }; - - Tour.prototype.resume = function() { - var step; - step = this.getStep(this._current); - if (!(step && step.duration)) { - return this; - } - this._paused = false; - this._start = new Date().getTime(); - this._duration = this._duration || step.duration; - this._timer = window.setTimeout((function(_this) { - return function() { - if (_this._isLast()) { - return _this.next(); - } else { - return _this.end(); - } - }; - })(this), this._duration); - this._debug("Started step " + (this._current + 1) + " timer with duration " + this._duration); - if ((step.onResume != null) && this._duration !== step.duration) { - return step.onResume(this, this._duration); - } - }; - - Tour.prototype.hideStep = function(i) { - var hideStepHelper, promise, step; - step = this.getStep(i); - if (!step) { - return; - } - this._clearTimer(); - promise = this._makePromise(step.onHide != null ? step.onHide(this, i) : void 0); - hideStepHelper = (function(_this) { - return function(e) { - var $element; - $element = $(step.element); - if (!($element.data("bs.popover") || $element.data("popover"))) { - $element = $("body"); - } - $element.popover("destroy").removeClass("tour-" + _this._options.name + "-element tour-" + _this._options.name + "-" + i + "-element"); - if (step.reflex) { - $element.css("cursor", "").off("click.tour-" + _this._options.name); - } - if (step.backdrop) { - _this._hideBackdrop(); - } - if (step.onHidden != null) { - return step.onHidden(_this); - } - }; - })(this); - this._callOnPromiseDone(promise, hideStepHelper); - return promise; - }; - - Tour.prototype.showStep = function(i) { - var promise, showStepHelper, skipToPrevious, step; - if (this.ended()) { - this._debug("Tour ended, showStep prevented."); - return this; - } - step = this.getStep(i); - if (!step) { - return; - } - skipToPrevious = i < this._current; - promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0); - showStepHelper = (function(_this) { - return function(e) { - var current_path, path; - _this.setCurrentStep(i); - path = (function() { - switch ({}.toString.call(step.path)) { - case "[object Function]": - return step.path(); - case "[object String]": - return this._options.basePath + step.path; - default: - return step.path; - } - }).call(_this); - current_path = [document.location.pathname, document.location.hash].join(""); - if (_this._isRedirect(path, current_path)) { - _this._redirect(step, path); - return; - } - if (_this._isOrphan(step)) { - if (!step.orphan) { - _this._debug("Skip the orphan step " + (_this._current + 1) + ". Orphan option is false and the element doesn't exist or is hidden."); - if (skipToPrevious) { - _this._showPrevStep(); - } else { - _this._showNextStep(); - } - return; - } - _this._debug("Show the orphan step " + (_this._current + 1) + ". Orphans option is true."); - } - if (step.backdrop) { - _this._showBackdrop(!_this._isOrphan(step) ? step.element : void 0); - } - _this._scrollIntoView(step.element, function() { - if ((step.element != null) && step.backdrop) { - _this._showOverlayElement(step.element); - } - _this._showPopover(step, i); - if (step.onShown != null) { - step.onShown(_this); - } - return _this._debug("Step " + (_this._current + 1) + " of " + _this._options.steps.length); - }); - if (step.duration) { - return _this.resume(); - } - }; - })(this); - this._callOnPromiseDone(promise, showStepHelper); - return promise; - }; - - Tour.prototype.getCurrentStep = function() { - return this._current; - }; - - Tour.prototype.setCurrentStep = function(value) { - if (value != null) { - this._current = value; - this._setState("current_step", value); - } else { - this._current = this._getState("current_step"); - this._current = this._current === null ? null : parseInt(this._current, 10); - } - return this; - }; - - Tour.prototype._setState = function(key, value) { - var e, keyName; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - try { - this._options.storage.setItem(keyName, value); - } catch (_error) { - e = _error; - if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { - this.debug("LocalStorage quota exceeded. State storage failed."); - } - } - return this._options.afterSetState(keyName, value); - } else { - if (this._state == null) { - this._state = {}; - } - return this._state[key] = value; - } - }; - - Tour.prototype._removeState = function(key) { - var keyName; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - this._options.storage.removeItem(keyName); - return this._options.afterRemoveState(keyName); - } else { - if (this._state != null) { - return delete this._state[key]; - } - } - }; - - Tour.prototype._getState = function(key) { - var keyName, value; - if (this._options.storage) { - keyName = "" + this._options.name + "_" + key; - value = this._options.storage.getItem(keyName); - } else { - if (this._state != null) { - value = this._state[key]; - } - } - if (value === void 0 || value === "null") { - value = null; - } - this._options.afterGetState(key, value); - return value; - }; - - Tour.prototype._showNextStep = function() { - var promise, showNextStepHelper, step; - step = this.getStep(this._current); - showNextStepHelper = (function(_this) { - return function(e) { - return _this.showStep(step.next); - }; - })(this); - promise = this._makePromise(step.onNext != null ? step.onNext(this) : void 0); - return this._callOnPromiseDone(promise, showNextStepHelper); - }; - - Tour.prototype._showPrevStep = function() { - var promise, showPrevStepHelper, step; - step = this.getStep(this._current); - showPrevStepHelper = (function(_this) { - return function(e) { - return _this.showStep(step.prev); - }; - })(this); - promise = this._makePromise(step.onPrev != null ? step.onPrev(this) : void 0); - return this._callOnPromiseDone(promise, showPrevStepHelper); - }; - - Tour.prototype._debug = function(text) { - if (this._options.debug) { - return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + text); - } - }; - - Tour.prototype._isRedirect = function(path, currentPath) { - return (path != null) && path !== "" && ((toString.call(path) === "[object RegExp]" && !path.test(currentPath)) || (toString.call(path) === "[object String]" && path.replace(/\?.*$/, "").replace(/\/?$/, "") !== currentPath.replace(/\/?$/, ""))); - }; - - Tour.prototype._redirect = function(step, path) { - if ($.isFunction(step.redirect)) { - return step.redirect.call(this, path); - } else if (step.redirect === true) { - this._debug("Redirect to " + path); - return document.location.href = path; - } - }; - - Tour.prototype._isOrphan = function(step) { - return (step.element == null) || !$(step.element).length || $(step.element).is(":hidden") && ($(step.element)[0].namespaceURI !== "http://www.w3.org/2000/svg"); - }; - - Tour.prototype._isLast = function() { - return this._current < this._options.steps.length - 1; - }; - - Tour.prototype._showPopover = function(step, i) { - var $element, $navigation, $template, $tip, isOrphan, options; - options = $.extend({}, this._options); - $template = $.isFunction(step.template) ? $(step.template(i, step)) : $(step.template); - $navigation = $template.find(".popover-navigation"); - isOrphan = this._isOrphan(step); - if (isOrphan) { - step.element = "body>*:last"; - step.placement = "top"; - $template = $template.addClass("orphan"); - } - $element = $(step.element); - $template.addClass("tour-" + this._options.name + " tour-" + this._options.name + "-" + i); - $element.addClass("tour-" + this._options.name + "-element tour-" + this._options.name + "-" + i + "-element"); - if (step.options) { - $.extend(options, step.options); - } - if (step.reflex) { - $element.css("cursor", "pointer").on("click.tour-" + this._options.name, (function(_this) { - return function() { - if (_this._isLast()) { - return _this.next(); - } else { - return _this.end(); - } - }; - })(this)); - } - if (step.prev < 0) { - $navigation.find("[data-role='prev']").addClass("disabled"); - } - if (step.next < 0) { - $navigation.find("[data-role='next']").addClass("disabled"); - } - if (!step.duration) { - $navigation.find("[data-role='pause-resume']").remove(); - } - step.template = $template.clone().wrap("
    ").parent().html(); - $element.popover({ - placement: step.placement, - trigger: "manual", - title: step.title, - content: step.content, - html: true, - animation: step.animation, - container: step.container, - template: step.template, - selector: step.element - }).popover("show"); - $tip = $element.data("bs.popover") ? $element.data("bs.popover").tip() : $element.data("popover").tip(); - $tip.attr("id", step.id); - this._reposition($tip, step); - if (isOrphan) { - return this._center($tip); - } - }; - - Tour.prototype._reposition = function($tip, step) { - var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; - offsetWidth = $tip[0].offsetWidth; - offsetHeight = $tip[0].offsetHeight; - tipOffset = $tip.offset(); - originalLeft = tipOffset.left; - originalTop = tipOffset.top; - offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); - if (offsetBottom < 0) { - tipOffset.top = tipOffset.top + offsetBottom; - } - offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); - if (offsetRight < 0) { - tipOffset.left = tipOffset.left + offsetRight; - } - if (tipOffset.top < 0) { - tipOffset.top = 0; - } - if (tipOffset.left < 0) { - tipOffset.left = 0; - } - $tip.offset(tipOffset); - if (step.placement === "bottom" || step.placement === "top") { - if (originalLeft !== tipOffset.left) { - return this._replaceArrow($tip, (tipOffset.left - originalLeft) * 2, offsetWidth, "left"); - } - } else { - if (originalTop !== tipOffset.top) { - return this._replaceArrow($tip, (tipOffset.top - originalTop) * 2, offsetHeight, "top"); - } - } - }; - - Tour.prototype._center = function($tip) { - return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); - }; - - Tour.prototype._replaceArrow = function($tip, delta, dimension, position) { - return $tip.find(".arrow").css(position, delta ? 50 * (1 - delta / dimension) + "%" : ""); - }; - - Tour.prototype._scrollIntoView = function(element, callback) { - var $element, $window, counter, offsetTop, scrollTop, windowHeight; - $element = $(element); - if (!$element.length) { - return callback(); - } - $window = $(window); - offsetTop = $element.offset().top; - windowHeight = $window.height(); - scrollTop = Math.max(0, offsetTop - (windowHeight / 2)); - this._debug("Scroll into view. ScrollTop: " + scrollTop + ". Element offset: " + offsetTop + ". Window height: " + windowHeight + "."); - counter = 0; - return $("body,html").stop(true, true).animate({ - scrollTop: Math.ceil(scrollTop) - }, (function(_this) { - return function() { - if (++counter === 2) { - callback(); - return _this._debug("Scroll into view. Animation end element offset: " + ($element.offset().top) + ". Window height: " + ($window.height()) + "."); - } - }; - })(this)); - }; - - Tour.prototype._onResize = function(callback, timeout) { - return $(window).on("resize.tour-" + this._options.name, function() { - clearTimeout(timeout); - return timeout = setTimeout(callback, 100); - }); - }; - - Tour.prototype._initMouseNavigation = function() { - var _this; - _this = this; - return $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']:not(.disabled)").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']:not(.disabled)").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']:not(.disabled)", (function(_this) { - return function(e) { - e.preventDefault(); - return _this.next(); - }; - })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']:not(.disabled)", (function(_this) { - return function(e) { - e.preventDefault(); - return _this.prev(); - }; - })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']", (function(_this) { - return function(e) { - e.preventDefault(); - return _this.end(); - }; - })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']", function(e) { - var $this; - e.preventDefault(); - $this = $(this); - $this.text(_this._paused ? $this.data("pause-text") : $this.data("resume-text")); - if (_this._paused) { - return _this.resume(); - } else { - return _this.pause(); - } - }); - }; - - Tour.prototype._initKeyboardNavigation = function() { - if (!this._options.keyboard) { - return; - } - return $(document).on("keyup.tour-" + this._options.name, (function(_this) { - return function(e) { - if (!e.which) { - return; - } - switch (e.which) { - case 39: - e.preventDefault(); - if (_this._isLast()) { - return _this.next(); - } else { - return _this.end(); - } - break; - case 37: - e.preventDefault(); - if (_this._current > 0) { - return _this.prev(); - } - break; - case 27: - e.preventDefault(); - return _this.end(); - } - }; - })(this)); - }; - - Tour.prototype._makePromise = function(result) { - if (result && $.isFunction(result.then)) { - return result; - } else { - return null; - } - }; - - Tour.prototype._callOnPromiseDone = function(promise, cb, arg) { - if (promise) { - return promise.then((function(_this) { - return function(e) { - return cb.call(_this, arg); - }; - })(this)); - } else { - return cb.call(this, arg); - } - }; - - Tour.prototype._showBackdrop = function(element) { - if (this.backdrop.backgroundShown) { - return; - } - this.backdrop = $("
    ", { - "class": "tour-backdrop" - }); - this.backdrop.backgroundShown = true; - return $("body").append(this.backdrop); - }; - - Tour.prototype._hideBackdrop = function() { - this._hideOverlayElement(); - return this._hideBackground(); - }; - - Tour.prototype._hideBackground = function() { - this.backdrop.remove(); - this.backdrop.overlay = null; - return this.backdrop.backgroundShown = false; - }; - - Tour.prototype._showOverlayElement = function(element) { - var $background, $element, offset; - $element = $(element); - if (!$element || $element.length === 0 || this.backdrop.overlayElementShown) { - return; - } - this.backdrop.overlayElementShown = true; - $background = $("
    "); - offset = $element.offset(); - offset.top = offset.top; - offset.left = offset.left; - $background.width($element.innerWidth()).height($element.innerHeight()).addClass("tour-step-background").offset(offset); - $element.addClass("tour-step-backdrop"); - $("body").append($background); - this.backdrop.$element = $element; - return this.backdrop.$background = $background; - }; - - Tour.prototype._hideOverlayElement = function() { - if (!this.backdrop.overlayElementShown) { - return; - } - this.backdrop.$element.removeClass("tour-step-backdrop"); - this.backdrop.$background.remove(); - this.backdrop.$element = null; - this.backdrop.$background = null; - return this.backdrop.overlayElementShown = false; - }; - - Tour.prototype._clearTimer = function() { - window.clearTimeout(this._timer); - this._timer = null; - return this._duration = null; - }; - - return Tour; - - })(); - return window.Tour = Tour; -})(jQuery, window); diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index da0fad43caf..0bd20bdcca9 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -484,10 +484,30 @@ div.tour-backdrop { z-index: 2009; } -.popover.tour { - z-index: 2010; +.popover.tour.orphan .arrow { + display: none; +} +.popover.tour .popover-navigation { + padding: 9px 14px; +} +.popover.tour .popover-navigation *[data-role="end"] { + float: right; +} +.popover.tour .popover-navigation *[data-role="next"], .popover.tour .popover-navigation *[data-role="end"] { + cursor: pointer; } .popover.fixed { position: fixed; } + +.tour-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1100; + background-color: black; + opacity: 0.8; +} diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index 4571dcd257e..bd0f4628009 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -424,9 +424,26 @@ $editorbar_height: 30px div.tour-backdrop z-index: 2009 .popover.tour - z-index: 2010 + &.orphan .arrow + display: none + .popover-navigation + padding: 9px 14px + *[data-role="end"] + float: right + *[data-role="next"],*[data-role="end"] + cursor: pointer .popover.fixed position: fixed +.tour-backdrop + position: fixed + top: 0 + right: 0 + bottom: 0 + left: 0 + z-index: 1100 + background-color: #000 + opacity: 0.8 + // }}} diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 443405e2401..a8abbcf59e2 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -13,6 +13,7 @@ title: _t("Welcome to your website!"), content: _t("This tutorial will guide you to build your home page. We will start by adding a banner."), popover: { next: _t("Start Tutorial"), end: _t("Skip It") }, + backdrop: true, }, { element: 'button[data-action=edit]', @@ -77,6 +78,7 @@ title: _t("Good Job!"), content: _t("Well done, you created your homepage."), popover: { next: _t("Continue") }, + backdrop: true, }, { element: 'a[data-action=show-mobile-preview]', diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index df6108e0278..3bfd4e06da0 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -15,8 +15,8 @@ if (typeof openerp === "undefined") { var website = window.openerp.website; -// don't rewrite website.Tour in test mode -if (typeof website.Tour !== "undefined") { +// don't rewrite T in test mode +if (typeof T !== "undefined") { return; } @@ -31,14 +31,14 @@ if (website.EditorBar) { start: function () { var self = this; var menu = $('#help-menu'); - _.each(website.Tour.tours, function (tour) { + _.each(T.tours, function (tour) { if (tour.mode === "test") { return; } var $menuItem = $($.parseHTML('
  • '+tour.name+'
  • ')); $menuItem.click(function () { - website.Tour.reset(); - website.Tour.run(tour.id); + T.reset(); + T.run(tour.id); }); menu.append($menuItem); }); @@ -80,32 +80,36 @@ $.ajaxSetup({ } }); - ///////////////////////////////////////////////// - var localStorage = window.localStorage; -website.Tour = {}; -website.Tour.tours = {}; -website.Tour.state = null; -website.Tour.register = function (tour) { +var T = website.Tour = {}; +T.tours = {}; +T.defaultDelay = 50; +T.errorDelay = 5000; +T.state = null; +T.$element = null; +T.timer = null; +T.testtimer = null; +T.currentTimer = null; +T.register = function (tour) { if (tour.mode !== "test") tour.mode = "tutorial"; - website.Tour.tours[tour.id] = tour; + T.tours[tour.id] = tour; }; -website.Tour.run = function (tour_id, mode) { +T.run = function (tour_id, mode) { if (localStorage.getItem("tour") && mode === "test") { // only one test running return; } - var tour = website.Tour.tours[tour_id]; - website.Tour.saveState(tour.id, mode || tour.mode, 0); - if (tour.path && !window.location.href.match(new RegExp("("+website.Tour.getLang()+")?"+tour.path+"#?$", "i"))) { - window.location.href = "/"+website.Tour.getLang()+tour.path; + var tour = T.tours[tour_id]; + T.saveState(tour.id, mode || tour.mode, 0); + if (tour.path && !window.location.href.match(new RegExp("("+T.getLang()+")?"+tour.path+"#?$", "i"))) { + window.location.href = "/"+T.getLang()+tour.path; } else { - website.Tour.running(); + T.running(); } }; -website.Tour.registerSteps = function (tour) { +T.registerSteps = function (tour) { if (tour.register) { return; } @@ -130,7 +134,10 @@ website.Tour.registerSteps = function (tour) { step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail'; } - if (!step.element) step.orphan = true; + if (!step.element) { + step.element = "body"; + step.orphan = true; + } } if (tour.steps[index-1] && tour.steps[index-1].popover && tour.steps[index-1].popover.next) { @@ -142,69 +149,151 @@ website.Tour.registerSteps = function (tour) { } // rendering bootstrap tour and popover - if (tour.mode !== "test" || typeof Tour !== "undefined") { - tour.tour = new Tour({ - debug: true, - name: tour.id, - storage: localStorage, - keyboard: false, - template: website.Tour.popover(), - onHide: function () { - window.scrollTo(0, 0); - } - }); - + if (tour.mode !== "test") { for (var index=0, len=tour.steps.length; index
    '); + } + + if (step.backdrop || $element.parents("#website-top-navbar, .modal").size()) { + $tip.css("z-index", 2010); + } + + // button click event + $tip.find("button") + .one("click", function () { + step.busy = true; + if (!$(this).is("[data-role='next']")) { + clearTimeout(T.timer); + T.endTour(); + } + T.closePopover(); + }); + + T.repositionPopover(); +}; +T.repositionPopover = function() { + var popover = T.$element.data("bs.popover"); + var $tip = T.$element.data("bs.popover").tip(); + + if (popover.options.orphan) { + return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); + } + + var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; + offsetWidth = $tip[0].offsetWidth; + offsetHeight = $tip[0].offsetHeight; + tipOffset = $tip.offset(); + originalLeft = tipOffset.left; + originalTop = tipOffset.top; + offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); + if (offsetBottom < 0) { + tipOffset.top = tipOffset.top + offsetBottom; + } + offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); + if (offsetRight < 0) { + tipOffset.left = tipOffset.left + offsetRight; + } + if (tipOffset.top < 0) { + tipOffset.top = 0; + } + if (tipOffset.left < 0) { + tipOffset.left = 0; + } + $tip.offset(tipOffset); + if (popover.options.placement === "bottom" || popover.options.placement === "top") { + var left = T.$element.offset().left + T.$element.outerWidth()/2 - tipOffset.left; + $tip.find(".arrow").css("left", left ? left + "px" : ""); } else { - tour.end(); + var top = T.$element.offset().top + T.$element.outerHeight()/2 - tipOffset.top; + $tip.find(".arrow").css("top", top ? top + "px" : ""); } }; -website.Tour.popoverTitle = function (tour, options) { +T.popoverTitle = function (tour, options) { return openerp.qweb.render('website.tour_popover_title', options); }; -website.Tour.popover = function (options) { +T.popover = function (options) { return openerp.qweb.render('website.tour_popover', options); }; -website.Tour.getLang = function () { +T.getLang = function () { return $("html").attr("lang").replace(/-/, '_'); }; -website.Tour.getState = function () { +T.getState = function () { var state = JSON.parse(localStorage.getItem("tour") || 'false') || {}; var tour_id,mode,step_id; if (!state.id && window.location.href.indexOf("#tutorial.") > -1) { @@ -217,15 +306,16 @@ website.Tour.getState = function () { if (!state.id) { return; } - state.tour = website.Tour.tours[state.id]; + state.tour = T.tours[state.id]; state.step = state.tour.steps[state.step_id]; return state; }; -website.Tour.error = function (tour, step, message) { - website.Tour.reset(); +T.error = function (message) { + var state = T.getState(); + T.reset(); throw new Error(message + - + "\ntour: " + tour.id + - + "\nstep: " + step.id + ": '" + (step._title || step.title) + "'" + + "\ntour: " + state.tour.id + + + "\nstep: " + state.step.id + ": '" + (state.step._title || state.step.title) + "'" + '\nhref: ' + window.location.href + '\nreferrer: ' + document.referrer + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) @@ -235,124 +325,121 @@ website.Tour.error = function (tour, step, message) { + '\n\n' + $("body").html() ); }; -website.Tour.lists = function () { +T.lists = function () { var tour_ids = []; - for (var k in website.Tour.tours) { + for (var k in T.tours) { tour_ids.push(k); } return tour_ids; }; -website.Tour.saveState = function (tour_id, mode, step_id) { - localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id})); +T.saveState = function (tour_id, mode, step_id) { + localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id || 0})); }; -website.Tour.reset = function () { - var state = website.Tour.getState(); +T.reset = function () { + var state = T.getState(); if (state) { for (var k in state.tour.steps) { state.tour.steps[k].busy = false; } - if (state.tour.tour) { - state.tour.tour.end(); - } } localStorage.removeItem("tour"); - clearTimeout(website.Tour.timer); - clearTimeout(website.Tour.testtimer); - - $(".popover.tour").remove(); + clearTimeout(T.timer); + clearTimeout(T.testtimer); + T.closePopover(); }; -website.Tour.running = function () { - var state = website.Tour.getState(); +T.running = function () { + var state = T.getState(); if (state) { - website.Tour.registerSteps(state.tour); + T.registerSteps(state.tour); if ($.ajaxBusy) { $(document).ajaxStop(function() { setTimeout(function () { - website.Tour.nextStep( state.tour, state.step, state.mode === "test" ? 5000 : 0 ); + T.nextStep(); },0); }); } else { - website.Tour.nextStep( state.tour, state.step, state.mode === "test" ? 5000 : 0 ); + T.nextStep(); } } }; - -website.Tour.timer = null; -website.Tour.testtimer = null; -website.Tour.defaultDelay = 50; -website.Tour.check = function (step) { +T.check = function (step) { return (step && (!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) && (!step.waitNot || !$(step.waitNot).size()) && (!step.waitFor || $(step.waitFor).size())); }; -website.Tour.waitNextStep = function (tour, step, overlaps) { +T.waitNextStep = function () { + var state = T.getState(); var time = new Date().getTime(); var timer; - var next = tour.steps[step.id+1]; + var next = state.tour.steps[state.step.id+1]; + var overlaps = state.mode === "test" ? T.errorDelay : 0; window.onbeforeunload = function () { - clearTimeout(website.Tour.timer); - clearTimeout(website.Tour.testtimer); + clearTimeout(T.timer); + clearTimeout(T.testtimer); }; function checkNext () { - website.Tour.autoToggleBootstrapTour(); + T.autoTogglePopover(); - clearTimeout(website.Tour.timer); - if (next.busy) return; - if (website.Tour.check(next)) { - next.busy = true; - clearTimeout(website.Tour.currentTimer); + clearTimeout(T.timer); + if (T.check(next)) { + clearTimeout(T.currentTimer); // use an other timeout for cke dom loading setTimeout(function () { - website.Tour.nextStep(tour, next, overlaps); - }, website.Tour.defaultDelay); + T.nextStep(next); + }, T.defaultDelay); } else if (!overlaps || new Date().getTime() - time < overlaps) { - website.Tour.timer = setTimeout(checkNext, website.Tour.defaultDelay); + T.timer = setTimeout(checkNext, T.defaultDelay); } else { - website.Tour.error(tour, next, "Can't arrive to the next step"); + T.error("Can't arrive to the next step"); } } checkNext(); }; -website.Tour.currentTimer = null; -website.Tour.nextStep = function (tour, step, overlaps) { - var state = website.Tour.getState(); - website.Tour.saveState(state.id, state.mode, step.id); +T.nextStep = function (step) { + var state = T.getState(); - website.Tour.autoToggleBootstrapTour(); + if (!state) { + return; + } + + step = step || state.step; + T.saveState(state.id, state.mode, step.id); + + T.autoTogglePopover(true); if (step.onload) { step.onload(); } - var next = tour.steps[step.id+1]; + var next = state.tour.steps[step.id+1]; if (next) { setTimeout(function () { - website.Tour.waitNextStep(tour, step, overlaps); + T.waitNextStep(); if (state.mode === "test") { setTimeout(function(){ - website.Tour.autoNextStep(tour, step); - }, website.Tour.defaultDelay); + T.autoNextStep(); + }, T.defaultDelay); } }, next.wait || 0); } else { - website.Tour.endTour(tour); + T.endTour(); } }; -website.Tour.endTour = function (tour) { - var state = website.Tour.getState(); +T.endTour = function () { + var state = T.getState(); var test = state.step.id >= state.tour.steps.length-1; - website.Tour.reset(); + T.reset(); if (test) { console.log('ok'); } else { console.log('error'); } }; -website.Tour.autoNextStep = function (tour, step) { - clearTimeout(website.Tour.testtimer); +T.autoNextStep = function (tour, step) { + clearTimeout(T.testtimer); function autoStep () { if (!step) return; @@ -361,18 +448,14 @@ website.Tour.autoNextStep = function (tour, step) { step.autoComplete(tour); } - var $popover = $(".popover.tour"); - if ($popover.find("button[data-role='next']:visible").size()) { - $popover.find("button[data-role='next']:visible").click(); - $popover.remove(); - } + T.closePopover(); var $element = $(step.element); if (!$element.size()) return; if (step.snippet) { - website.Tour.autoDragAndDropSnippet($element); + T.autoDragAndDropSnippet($element); } else if (step.sampleText) { @@ -388,7 +471,7 @@ website.Tour.autoNextStep = function (tour, step) { setTimeout(function () { $element.trigger($.Event("keyup", { srcElement: $element })); $element.trigger($.Event("change", { srcElement: $element })); - }, website.Tour.defaultDelay<<1); + }, T.defaultDelay<<1); } else if ($element.is(":visible")) { @@ -406,9 +489,9 @@ website.Tour.autoNextStep = function (tour, step) { }, 1000); } } - website.Tour.testtimer = setTimeout(autoStep, 100); + T.testtimer = setTimeout(autoStep, 100); }; -website.Tour.autoDragAndDropSnippet = function (selector) { +T.autoDragAndDropSnippet = function (selector) { var $thumbnail = $(selector).first(); var thumbnailPosition = $thumbnail.position(); $thumbnail.trigger($.Event("mousedown", { which: 1, pageX: thumbnailPosition.left, pageY: thumbnailPosition.top })); @@ -418,8 +501,8 @@ website.Tour.autoDragAndDropSnippet = function (selector) { $dropZone.trigger($.Event("mouseup", { which: 1, pageX: dropPosition.left, pageY: dropPosition.top })); }; -//$(document).ready(website.Tour.running); -website.ready().then(website.Tour.running); +//$(document).ready(T.running); +website.ready().then(T.running); }()); From 254b3a29fa80ffcaeec2da60a2a2b0abac8da925 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 12:18:15 +0100 Subject: [PATCH 058/423] [IMP] website tour: auto set backdrop if no selector element bzr revid: chm@openerp.com-20140321111815-t0312xxl7l83w9rx --- addons/website/static/src/js/website.tour.banner.js | 2 -- addons/website/static/src/js/website.tour.js | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index a8abbcf59e2..443405e2401 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -13,7 +13,6 @@ title: _t("Welcome to your website!"), content: _t("This tutorial will guide you to build your home page. We will start by adding a banner."), popover: { next: _t("Start Tutorial"), end: _t("Skip It") }, - backdrop: true, }, { element: 'button[data-action=edit]', @@ -78,7 +77,6 @@ title: _t("Good Job!"), content: _t("Well done, you created your homepage."), popover: { next: _t("Continue") }, - backdrop: true, }, { element: 'a[data-action=show-mobile-preview]', diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 3bfd4e06da0..ce20bf69718 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -137,6 +137,7 @@ T.registerSteps = function (tour) { if (!step.element) { step.element = "body"; step.orphan = true; + step.backdrop = true; } } if (tour.steps[index-1] && From 429324999c9fe7149e34ec5f501c14aa7a8a7fdc Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 12:23:44 +0100 Subject: [PATCH 059/423] [IMP] website tour: remove tag script and css to lib bootstrap bzr revid: chm@openerp.com-20140321112344-mwh2p8pp02j9sdq0 --- addons/website/views/website_templates.xml | 2 -- addons/website_report/views/layouts.xml | 2 -- 2 files changed, 4 deletions(-) diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 66a38f09651..7849c701bd4 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -253,7 +253,6 @@ - @@ -265,7 +264,6 @@ - diff --git a/addons/website_report/views/layouts.xml b/addons/website_report/views/layouts.xml index 091bb8dd3db..219780317c3 100644 --- a/addons/website_report/views/layouts.xml +++ b/addons/website_report/views/layouts.xml @@ -33,7 +33,6 @@ - @@ -42,7 +41,6 @@ - From d8f27686e5e70a626d12d4fcfdc6af5e5e642468 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 12:57:24 +0100 Subject: [PATCH 060/423] [IMP] website tour: fix test tour bzr revid: chm@openerp.com-20140321115724-iwu17fkzdzaksmrs --- addons/website/static/src/js/website.tour.js | 25 ++++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index ce20bf69718..26fa5af0b9f 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -313,18 +313,17 @@ T.getState = function () { }; T.error = function (message) { var state = T.getState(); + message += '\n tour: ' + state.id + + '\n step: ' + state.step_id + ": '" + (state.step._title || state.step.title) + "'" + + '\n href: ' + window.location.href + + '\n referrer: ' + document.referrer + + '\n element: ' + Boolean(!state.step.element || ($(state.step.element).size() && $(state.step.element).is(":visible") && !$(state.step.element).is(":hidden"))) + + '\n waitNot: ' + Boolean(!state.step.waitNot || !$(state.step.waitNot).size()) + + '\n waitFor: ' + Boolean(!state.step.waitFor || $(state.step.waitFor).size()) + + "\n localStorage: " + JSON.stringify(localStorage) + + '\n\n' + $("body").html(); T.reset(); - throw new Error(message + - + "\ntour: " + state.tour.id + - + "\nstep: " + state.step.id + ": '" + (state.step._title || state.step.title) + "'" - + '\nhref: ' + window.location.href - + '\nreferrer: ' + document.referrer - + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) - + '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) - + '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) - + "\nlocalStorage: " + JSON.stringify(localStorage) - + '\n\n' + $("body").html() - ); + throw new Error(message); }; T.lists = function () { var tour_ids = []; @@ -421,7 +420,7 @@ T.nextStep = function (step) { T.waitNextStep(); if (state.mode === "test") { setTimeout(function(){ - T.autoNextStep(); + T.autoNextStep(state.tour, step); }, T.defaultDelay); } }, next.wait || 0); @@ -449,7 +448,7 @@ T.autoNextStep = function (tour, step) { step.autoComplete(tour); } - T.closePopover(); + $(".popover.tour [data-role='next']").click(); var $element = $(step.element); if (!$element.size()) return; From 89a6bd06495c4fe599756866828298331f375747 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 13:37:22 +0100 Subject: [PATCH 061/423] [IMP] website tour: fix auto test bzr revid: chm@openerp.com-20140321123722-dmfdckh59cvot00i --- addons/website/static/src/js/website.tour.js | 4 ++-- .../static/src/js/website.tour.event_sale.js | 4 ++-- addons/website_sale/static/src/js/website.tour.sale.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 26fa5af0b9f..a033e6f1ecd 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -16,7 +16,7 @@ if (typeof openerp === "undefined") { var website = window.openerp.website; // don't rewrite T in test mode -if (typeof T !== "undefined") { +if (typeof website.Tour !== "undefined") { return; } @@ -393,7 +393,7 @@ T.waitNextStep = function () { } else if (!overlaps || new Date().getTime() - time < overlaps) { T.timer = setTimeout(checkNext, T.defaultDelay); } else { - T.error("Can't arrive to the next step"); + T.error("Can't reach the next step"); } } checkNext(); diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js index 92e57638cc8..668a05001af 100644 --- a/addons/website_event_sale/static/src/js/website.tour.event_sale.js +++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js @@ -16,7 +16,7 @@ { title: "go to register page", waitNot: 'a[href*="/event"]:contains("Functional Webinar")', - onload: function () { + autoComplete: function () { // use onload if website_event_track is installed if (!$('form:contains("Ticket Type")').size()) { window.location.href = $('a[href*="/event"][href*="/register"]').attr("href"); @@ -43,7 +43,7 @@ title: "Complete checkout", waitFor: '#top_menu .my_cart_quantity:contains(5)', element: 'form[action="/shop/confirm_order"] .btn:contains("Confirm")', - onload: function (tour) { + autoComplete: function (tour) { if ($("input[name='name']").val() === "") $("input[name='name']").val("website_sale-test-shoptest"); if ($("input[name='email']").val() === "") diff --git a/addons/website_sale/static/src/js/website.tour.sale.js b/addons/website_sale/static/src/js/website.tour.sale.js index c7526b2468f..62455e0b811 100644 --- a/addons/website_sale/static/src/js/website.tour.sale.js +++ b/addons/website_sale/static/src/js/website.tour.sale.js @@ -50,7 +50,7 @@ { title: "test with input error", element: 'form[action="/shop/confirm_order"] .btn:contains("Confirm")', - onload: function (tour) { + autoComplete: function (tour) { $("input[name='phone']").val(""); }, }, @@ -58,7 +58,7 @@ title: "test without input error", waitFor: 'form[action="/shop/confirm_order"] .has-error', element: 'form[action="/shop/confirm_order"] .btn:contains("Confirm")', - onload: function (tour) { + autoComplete: function (tour) { if ($("input[name='name']").val() === "") $("input[name='name']").val("website_sale-test-shoptest"); if ($("input[name='email']").val() === "") From f9b0c7469a7762bbba6d142e7799fc854aa01d24 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 14:42:07 +0100 Subject: [PATCH 062/423] [IMP] website tour: change syntax bzr revid: chm@openerp.com-20140321134207-y54uj2fynl5p0e8a --- addons/website/static/src/js/website.tour.js | 795 ++++++++++--------- 1 file changed, 399 insertions(+), 396 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index a033e6f1ecd..6a5f8faab76 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -84,421 +84,424 @@ $.ajaxSetup({ var localStorage = window.localStorage; -var T = website.Tour = {}; -T.tours = {}; -T.defaultDelay = 50; -T.errorDelay = 5000; -T.state = null; -T.$element = null; -T.timer = null; -T.testtimer = null; -T.currentTimer = null; -T.register = function (tour) { - if (tour.mode !== "test") tour.mode = "tutorial"; - T.tours[tour.id] = tour; -}; -T.run = function (tour_id, mode) { - if (localStorage.getItem("tour") && mode === "test") { // only one test running - return; - } - var tour = T.tours[tour_id]; - T.saveState(tour.id, mode || tour.mode, 0); - if (tour.path && !window.location.href.match(new RegExp("("+T.getLang()+")?"+tour.path+"#?$", "i"))) { - window.location.href = "/"+T.getLang()+tour.path; - } else { - T.running(); - } -}; -T.registerSteps = function (tour) { - if (tour.register) { - return; - } - tour.register = true; - - for (var index=0, len=tour.steps.length; index 0 && tour.steps[index-1] && - tour.steps[index-1].popover && tour.steps[index-1].popover.next) { - step.waitNot = '.popover.tour.fade.in:visible'; +var T = website.Tour = { + tours: {}, + defaultDelay: 50, + errorDelay: 5000, + state: null, + $element: null, + timer: null, + testtimer: null, + currentTimer: null, + register: function (tour) { + if (tour.mode !== "test") tour.mode = "tutorial"; + T.tours[tour.id] = tour; + }, + run: function (tour_id, mode) { + if (localStorage.getItem("tour") && mode === "test") { // only one test running + return; } - if (!step.waitFor && index > 0 && tour.steps[index-1].snippet) { - step.waitFor = '.oe_overlay_options .oe_options:visible'; + var tour = T.tours[tour_id]; + T.saveState(tour.id, mode || tour.mode, 0); + if (tour.path && !window.location.href.match(new RegExp("("+T.getLang()+")?"+tour.path+"#?$", "i"))) { + window.location.href = "/"+T.getLang()+tour.path; + } else { + T.running(); } - - var snippet = step.element && step.element.match(/#oe_snippets (.*) \.oe_snippet_thumbnail/); - if (snippet) { - step.snippet = snippet[1]; - } else if (step.snippet) { - step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail'; + }, + registerSteps: function (tour) { + if (tour.register) { + return; } + tour.register = true; - if (!step.element) { - step.element = "body"; - step.orphan = true; - step.backdrop = true; - } - } - if (tour.steps[index-1] && - tour.steps[index-1].popover && tour.steps[index-1].popover.next) { - var step = { - id: index, - waitNot: '.popover.tour.fade.in:visible' - }; - tour.steps.push(step); - } - - // rendering bootstrap tour and popover - if (tour.mode !== "test") { for (var index=0, len=tour.steps.length; index
    '); - } - - if (step.backdrop || $element.parents("#website-top-navbar, .modal").size()) { - $tip.css("z-index", 2010); - } - - // button click event - $tip.find("button") - .one("click", function () { - step.busy = true; - if (!$(this).is("[data-role='next']")) { - clearTimeout(T.timer); - T.endTour(); + if (!step.waitNot && index > 0 && tour.steps[index-1] && + tour.steps[index-1].popover && tour.steps[index-1].popover.next) { + step.waitNot = '.popover.tour.fade.in:visible'; + } + if (!step.waitFor && index > 0 && tour.steps[index-1].snippet) { + step.waitFor = '.oe_overlay_options .oe_options:visible'; } - T.closePopover(); - }); - T.repositionPopover(); -}; -T.repositionPopover = function() { - var popover = T.$element.data("bs.popover"); - var $tip = T.$element.data("bs.popover").tip(); + var snippet = step.element && step.element.match(/#oe_snippets (.*) \.oe_snippet_thumbnail/); + if (snippet) { + step.snippet = snippet[1]; + } else if (step.snippet) { + step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail'; + } - if (popover.options.orphan) { - return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); - } - - var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; - offsetWidth = $tip[0].offsetWidth; - offsetHeight = $tip[0].offsetHeight; - tipOffset = $tip.offset(); - originalLeft = tipOffset.left; - originalTop = tipOffset.top; - offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); - if (offsetBottom < 0) { - tipOffset.top = tipOffset.top + offsetBottom; - } - offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); - if (offsetRight < 0) { - tipOffset.left = tipOffset.left + offsetRight; - } - if (tipOffset.top < 0) { - tipOffset.top = 0; - } - if (tipOffset.left < 0) { - tipOffset.left = 0; - } - $tip.offset(tipOffset); - if (popover.options.placement === "bottom" || popover.options.placement === "top") { - var left = T.$element.offset().left + T.$element.outerWidth()/2 - tipOffset.left; - $tip.find(".arrow").css("left", left ? left + "px" : ""); - } else { - var top = T.$element.offset().top + T.$element.outerHeight()/2 - tipOffset.top; - $tip.find(".arrow").css("top", top ? top + "px" : ""); - } -}; -T.popoverTitle = function (tour, options) { - return openerp.qweb.render('website.tour_popover_title', options); -}; -T.popover = function (options) { - return openerp.qweb.render('website.tour_popover', options); -}; -T.getLang = function () { - return $("html").attr("lang").replace(/-/, '_'); -}; -T.getState = function () { - var state = JSON.parse(localStorage.getItem("tour") || 'false') || {}; - var tour_id,mode,step_id; - if (!state.id && window.location.href.indexOf("#tutorial.") > -1) { - state = { - "id": window.location.href.match(/#tutorial\.(.*)=true/)[1], - "mode": "tutorial", - "step_id": 0 - }; - } - if (!state.id) { - return; - } - state.tour = T.tours[state.id]; - state.step = state.tour.steps[state.step_id]; - return state; -}; -T.error = function (message) { - var state = T.getState(); - message += '\n tour: ' + state.id - + '\n step: ' + state.step_id + ": '" + (state.step._title || state.step.title) + "'" - + '\n href: ' + window.location.href - + '\n referrer: ' + document.referrer - + '\n element: ' + Boolean(!state.step.element || ($(state.step.element).size() && $(state.step.element).is(":visible") && !$(state.step.element).is(":hidden"))) - + '\n waitNot: ' + Boolean(!state.step.waitNot || !$(state.step.waitNot).size()) - + '\n waitFor: ' + Boolean(!state.step.waitFor || $(state.step.waitFor).size()) - + "\n localStorage: " + JSON.stringify(localStorage) - + '\n\n' + $("body").html(); - T.reset(); - throw new Error(message); -}; -T.lists = function () { - var tour_ids = []; - for (var k in T.tours) { - tour_ids.push(k); - } - return tour_ids; -}; -T.saveState = function (tour_id, mode, step_id) { - localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id || 0})); -}; -T.reset = function () { - var state = T.getState(); - if (state) { - for (var k in state.tour.steps) { - state.tour.steps[k].busy = false; + if (!step.element) { + step.element = "body"; + step.orphan = true; + step.backdrop = true; + } } - } - localStorage.removeItem("tour"); - clearTimeout(T.timer); - clearTimeout(T.testtimer); - T.closePopover(); -}; -T.running = function () { - var state = T.getState(); - if (state) { - T.registerSteps(state.tour); - if ($.ajaxBusy) { - $(document).ajaxStop(function() { - setTimeout(function () { - T.nextStep(); - },0); + if (tour.steps[index-1] && + tour.steps[index-1].popover && tour.steps[index-1].popover.next) { + var step = { + id: index, + waitNot: '.popover.tour.fade.in:visible' + }; + tour.steps.push(step); + } + + // rendering bootstrap tour and popover + if (tour.mode !== "test") { + for (var index=0, len=tour.steps.length; index
    '); + } + + if (step.backdrop || $element.parents("#website-top-navbar, .modal").size()) { + $tip.css("z-index", 2010); + } + + // button click event + $tip.find("button") + .one("click", function () { + step.busy = true; + if (!$(this).is("[data-role='next']")) { + clearTimeout(T.timer); + T.endTour(); + } + T.closePopover(); }); - } else { - T.nextStep(); - } - } -}; -T.check = function (step) { - return (step && - (!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) && - (!step.waitNot || !$(step.waitNot).size()) && - (!step.waitFor || $(step.waitFor).size())); -}; -T.waitNextStep = function () { - var state = T.getState(); - var time = new Date().getTime(); - var timer; - var next = state.tour.steps[state.step.id+1]; - var overlaps = state.mode === "test" ? T.errorDelay : 0; - window.onbeforeunload = function () { + T.repositionPopover(); + }, + repositionPopover: function() { + var popover = T.$element.data("bs.popover"); + var $tip = T.$element.data("bs.popover").tip(); + + if (popover.options.orphan) { + return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); + } + + var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; + offsetWidth = $tip[0].offsetWidth; + offsetHeight = $tip[0].offsetHeight; + tipOffset = $tip.offset(); + originalLeft = tipOffset.left; + originalTop = tipOffset.top; + offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); + if (offsetBottom < 0) { + tipOffset.top = tipOffset.top + offsetBottom; + } + offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); + if (offsetRight < 0) { + tipOffset.left = tipOffset.left + offsetRight; + } + if (tipOffset.top < 0) { + tipOffset.top = 0; + } + if (tipOffset.left < 0) { + tipOffset.left = 0; + } + $tip.offset(tipOffset); + if (popover.options.placement === "bottom" || popover.options.placement === "top") { + var left = T.$element.offset().left + T.$element.outerWidth()/2 - tipOffset.left; + $tip.find(".arrow").css("left", left ? left + "px" : ""); + } else if (popover.options.placement !== "auto") { + var top = T.$element.offset().top + T.$element.outerHeight()/2 - tipOffset.top; + $tip.find(".arrow").css("top", top ? top + "px" : ""); + } + }, + popoverTitle: function (tour, options) { + return openerp.qweb.render('website.tour_popover_title', options); + }, + popover: function (options) { + return openerp.qweb.render('website.tour_popover', options); + }, + getLang: function () { + return $("html").attr("lang").replace(/-/, '_'); + }, + getState: function () { + var state = JSON.parse(localStorage.getItem("tour") || 'false') || {}; + var tour_id,mode,step_id; + if (!state.id && window.location.href.indexOf("#tutorial.") > -1) { + state = { + "id": window.location.href.match(/#tutorial\.(.*)=true/)[1], + "mode": "tutorial", + "step_id": 0 + }; + window.location.hash = ""; + T.saveState(state.id, state.mode, state.step_id); + } + if (!state.id) { + return; + } + state.tour = T.tours[state.id]; + state.step = state.tour.steps[state.step_id]; + return state; + }, + error: function (message) { + var state = T.getState(); + message += '\n tour: ' + state.id + + '\n step: ' + state.step_id + ": '" + (state.step._title || state.step.title) + "'" + + '\n href: ' + window.location.href + + '\n referrer: ' + document.referrer + + '\n element: ' + Boolean(!state.step.element || ($(state.step.element).size() && $(state.step.element).is(":visible") && !$(state.step.element).is(":hidden"))) + + '\n waitNot: ' + Boolean(!state.step.waitNot || !$(state.step.waitNot).size()) + + '\n waitFor: ' + Boolean(!state.step.waitFor || $(state.step.waitFor).size()) + + "\n localStorage: " + JSON.stringify(localStorage) + + '\n\n' + $("body").html(); + T.reset(); + throw new Error(message); + }, + lists: function () { + var tour_ids = []; + for (var k in T.tours) { + tour_ids.push(k); + } + return tour_ids; + }, + saveState: function (tour_id, mode, step_id) { + localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id || 0})); + }, + reset: function () { + var state = T.getState(); + if (state) { + for (var k in state.tour.steps) { + state.tour.steps[k].busy = false; + } + } + localStorage.removeItem("tour"); clearTimeout(T.timer); clearTimeout(T.testtimer); - }; - - function checkNext () { - T.autoTogglePopover(); - - clearTimeout(T.timer); - if (T.check(next)) { - clearTimeout(T.currentTimer); - // use an other timeout for cke dom loading - setTimeout(function () { - T.nextStep(next); - }, T.defaultDelay); - } else if (!overlaps || new Date().getTime() - time < overlaps) { - T.timer = setTimeout(checkNext, T.defaultDelay); - } else { - T.error("Can't reach the next step"); - } - } - checkNext(); -}; -T.nextStep = function (step) { - var state = T.getState(); - - if (!state) { - return; - } - - step = step || state.step; - T.saveState(state.id, state.mode, step.id); - - T.autoTogglePopover(true); - - if (step.onload) { - step.onload(); - } - - var next = state.tour.steps[step.id+1]; - if (next) { - setTimeout(function () { - T.waitNextStep(); - if (state.mode === "test") { - setTimeout(function(){ - T.autoNextStep(state.tour, step); - }, T.defaultDelay); - } - }, next.wait || 0); - } else { - T.endTour(); - } -}; -T.endTour = function () { - var state = T.getState(); - var test = state.step.id >= state.tour.steps.length-1; - T.reset(); - if (test) { - console.log('ok'); - } else { - console.log('error'); - } -}; -T.autoNextStep = function (tour, step) { - clearTimeout(T.testtimer); - - function autoStep () { - if (!step) return; - - if (step.autoComplete) { - step.autoComplete(tour); - } - - $(".popover.tour [data-role='next']").click(); - - var $element = $(step.element); - if (!$element.size()) return; - - if (step.snippet) { - - T.autoDragAndDropSnippet($element); - - } else if (step.sampleText) { - - $element.trigger($.Event("keydown", { srcElement: $element })); - if ($element.is("input") ) { - $element.val(step.sampleText); - } if ($element.is("select")) { - $element.find("[value='"+step.sampleText+"'], option:contains('"+step.sampleText+"')").attr("selected", true); - $element.val(step.sampleText); + T.closePopover(); + }, + running: function () { + var state = T.getState(); + if (state) { + T.registerSteps(state.tour); + if ($.ajaxBusy) { + $(document).ajaxStop(function() { + setTimeout(function () { + T.nextStep(); + },0); + }); } else { - $element.html(step.sampleText); + T.nextStep(); } - setTimeout(function () { - $element.trigger($.Event("keyup", { srcElement: $element })); - $element.trigger($.Event("change", { srcElement: $element })); - }, T.defaultDelay<<1); - - } else if ($element.is(":visible")) { - - $element.trigger($.Event("mouseenter", { srcElement: $element[0] })); - $element.trigger($.Event("mousedown", { srcElement: $element[0] })); - - var evt = document.createEvent("MouseEvents"); - evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); - $element[0].dispatchEvent(evt); - - // trigger after for step like: mouseenter, next step click on button display with mouseenter - setTimeout(function () { - $element.trigger($.Event("mouseup", { srcElement: $element[0] })); - $element.trigger($.Event("mouseleave", { srcElement: $element[0] })); - }, 1000); } + }, + check: function (step) { + return (step && + (!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) && + (!step.waitNot || !$(step.waitNot).size()) && + (!step.waitFor || $(step.waitFor).size())); + }, + waitNextStep: function () { + var state = T.getState(); + var time = new Date().getTime(); + var timer; + var next = state.tour.steps[state.step.id+1]; + var overlaps = state.mode === "test" ? T.errorDelay : 0; + + window.onbeforeunload = function () { + clearTimeout(T.timer); + clearTimeout(T.testtimer); + }; + + function checkNext () { + T.autoTogglePopover(); + + clearTimeout(T.timer); + if (T.check(next)) { + clearTimeout(T.currentTimer); + // use an other timeout for cke dom loading + setTimeout(function () { + T.nextStep(next); + }, T.defaultDelay); + } else if (!overlaps || new Date().getTime() - time < overlaps) { + T.timer = setTimeout(checkNext, T.defaultDelay); + } else { + T.error("Can't reach the next step"); + } + } + checkNext(); + }, + nextStep: function (step) { + var state = T.getState(); + + if (!state) { + return; + } + + step = step || state.step; + T.saveState(state.id, state.mode, step.id); + + T.autoTogglePopover(true); + + if (step.onload) { + step.onload(); + } + + var next = state.tour.steps[step.id+1]; + if (next) { + setTimeout(function () { + T.waitNextStep(); + if (state.mode === "test") { + setTimeout(function(){ + T.autoNextStep(state.tour, step); + }, T.defaultDelay); + } + }, next.wait || 0); + } else { + T.endTour(); + } + }, + endTour: function () { + var state = T.getState(); + var test = state.step.id >= state.tour.steps.length-1; + T.reset(); + if (test) { + console.log('ok'); + } else { + console.log('error'); + } + }, + autoNextStep: function (tour, step) { + clearTimeout(T.testtimer); + + function autoStep () { + if (!step) return; + + if (step.autoComplete) { + step.autoComplete(tour); + } + + $(".popover.tour [data-role='next']").click(); + + var $element = $(step.element); + if (!$element.size()) return; + + if (step.snippet) { + + T.autoDragAndDropSnippet($element); + + } else if (step.sampleText) { + + $element.trigger($.Event("keydown", { srcElement: $element })); + if ($element.is("input") ) { + $element.val(step.sampleText); + } if ($element.is("select")) { + $element.find("[value='"+step.sampleText+"'], option:contains('"+step.sampleText+"')").attr("selected", true); + $element.val(step.sampleText); + } else { + $element.html(step.sampleText); + } + setTimeout(function () { + $element.trigger($.Event("keyup", { srcElement: $element })); + $element.trigger($.Event("change", { srcElement: $element })); + }, T.defaultDelay<<1); + + } else if ($element.is(":visible")) { + + $element.trigger($.Event("mouseenter", { srcElement: $element[0] })); + $element.trigger($.Event("mousedown", { srcElement: $element[0] })); + + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + $element[0].dispatchEvent(evt); + + // trigger after for step like: mouseenter, next step click on button display with mouseenter + setTimeout(function () { + $element.trigger($.Event("mouseup", { srcElement: $element[0] })); + $element.trigger($.Event("mouseleave", { srcElement: $element[0] })); + }, 1000); + } + } + T.testtimer = setTimeout(autoStep, 100); + }, + autoDragAndDropSnippet: function (selector) { + var $thumbnail = $(selector).first(); + var thumbnailPosition = $thumbnail.position(); + $thumbnail.trigger($.Event("mousedown", { which: 1, pageX: thumbnailPosition.left, pageY: thumbnailPosition.top })); + $thumbnail.trigger($.Event("mousemove", { which: 1, pageX: document.body.scrollWidth/2, pageY: document.body.scrollHeight/2 })); + var $dropZone = $(".oe_drop_zone").first(); + var dropPosition = $dropZone.position(); + $dropZone.trigger($.Event("mouseup", { which: 1, pageX: dropPosition.left, pageY: dropPosition.top })); } - T.testtimer = setTimeout(autoStep, 100); -}; -T.autoDragAndDropSnippet = function (selector) { - var $thumbnail = $(selector).first(); - var thumbnailPosition = $thumbnail.position(); - $thumbnail.trigger($.Event("mousedown", { which: 1, pageX: thumbnailPosition.left, pageY: thumbnailPosition.top })); - $thumbnail.trigger($.Event("mousemove", { which: 1, pageX: document.body.scrollWidth/2, pageY: document.body.scrollHeight/2 })); - var $dropZone = $(".oe_drop_zone").first(); - var dropPosition = $dropZone.position(); - $dropZone.trigger($.Event("mouseup", { which: 1, pageX: dropPosition.left, pageY: dropPosition.top })); }; //$(document).ready(T.running); From 24d37e284407a26987b1be3e539fa0243d81f656 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 21 Mar 2014 14:45:46 +0100 Subject: [PATCH 063/423] [FIX] website tour: template loading hide the real error bzr revid: chm@openerp.com-20140321134546-i5nw73en8thzrwc2 --- addons/website/static/src/js/website.tour.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 6a5f8faab76..eed431e071b 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -286,10 +286,10 @@ var T = website.Tour = { } }, popoverTitle: function (tour, options) { - return openerp.qweb.render('website.tour_popover_title', options); + return openerp.qweb ? openerp.qweb.render('website.tour_popover_title', options) : options.title; }, popover: function (options) { - return openerp.qweb.render('website.tour_popover', options); + return openerp.qweb ? openerp.qweb.render('website.tour_popover', options) : options.title; }, getLang: function () { return $("html").attr("lang").replace(/-/, '_'); From 0f40b3bc8f9c50e6e4361901eb9c024ba76851a3 Mon Sep 17 00:00:00 2001 From: Randhir Mayatra rma-openerp Date: Mon, 24 Mar 2014 10:39:21 +0530 Subject: [PATCH 064/423] [IMP] convert button into stat button for project_issue and stock_claim bzr revid: rma@tinyerp.com-20140324050921-qxn3n4getus3il6c --- .../claim_from_delivery/claim_delivery_view.xml | 7 ++++--- addons/crm/crm_lead.py | 11 ++++++++++- addons/crm/crm_lead_view.xml | 17 +++++++++-------- addons/crm_claim/crm_claim.py | 9 +++++++++ addons/crm_claim/res_partner_view.xml | 8 ++++---- addons/crm_project_issue/project_issue_view.xml | 3 ++- addons/project_issue/project_issue.py | 5 ++--- addons/stock/stock.py | 12 ++++++++++-- 8 files changed, 50 insertions(+), 22 deletions(-) diff --git a/addons/claim_from_delivery/claim_delivery_view.xml b/addons/claim_from_delivery/claim_delivery_view.xml index 9187b1d11ca..852d602c269 100644 --- a/addons/claim_from_delivery/claim_delivery_view.xml +++ b/addons/claim_from_delivery/claim_delivery_view.xml @@ -9,7 +9,6 @@ {'default_ref': 'stock.picking.out,'+str(context.get('active_id', False))} [('ref','=','stock.picking.out,'+str(context.get('active_id',False)))] - crm.claim.from_delivery.form stock.picking.out @@ -17,11 +16,13 @@
    -
    - diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 4da0a509ed1..b972fe34255 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -214,7 +214,14 @@ class crm_lead(format_address, osv.osv): duration = len(no_days) res[lead.id][field] = abs(int(duration)) return res - + def _meeting_count(self, cr, uid, ids, field_name, arg, context=None): + res = dict(map(lambda x: (x,0), ids)) + try: + for meeting in self.browse(cr, uid, ids, context=context): + res[meeting.id] = len(meeting.opportunity_ids) + except: + pass + return res _columns = { 'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange', select=True, help="Linked partner (optional). Usually created when converting the lead."), @@ -289,6 +296,8 @@ class crm_lead(format_address, osv.osv): 'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \ domain="[('section_id','=',section_id)]"), 'planned_cost': fields.float('Planned Costs'), + 'opportunity_ids': fields.one2many('calendar.event', 'opportunity_id', 'Opportunities'), + 'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'), } _defaults = { diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index a33b215fb8f..17c7f58c4fe 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -103,9 +103,8 @@
    -