mirror of
https://github.com/bringout/oca-ocb-web.git
synced 2026-04-22 21:52:03 +02:00
19.0 vanilla
This commit is contained in:
parent
20e6dadd87
commit
4b94f0abc5
205 changed files with 24700 additions and 14614 deletions
|
|
@ -1,5 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import res_users
|
||||
from . import ir_http
|
||||
from . import tour
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class Http(models.AbstractModel):
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
def session_info(self):
|
||||
result = super().session_info()
|
||||
if result['is_admin']:
|
||||
demo_modules_count = self.env['ir.module.module'].sudo().search_count([('demo', '=', True)])
|
||||
result['web_tours'] = self.env['web_tour.tour'].get_consumed_tours()
|
||||
result['tour_disable'] = demo_modules_count > 0
|
||||
result["tour_enabled"] = self.env.user.tour_enabled
|
||||
result['current_tour'] = self.env["web_tour.tour"].get_current_tour()
|
||||
return result
|
||||
|
|
|
|||
18
odoo-bringout-oca-ocb-web_tour/web_tour/models/res_users.py
Normal file
18
odoo-bringout-oca-ocb-web_tour/web_tour/models/res_users.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from odoo import models, fields, api, modules
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
tour_enabled = fields.Boolean(compute='_compute_tour_enabled', store=True, readonly=False, string="Onboarding")
|
||||
|
||||
@api.depends("create_date")
|
||||
def _compute_tour_enabled(self):
|
||||
demo_modules_count = self.env['ir.module.module'].sudo().search_count([('demo', '=', True)])
|
||||
for user in self:
|
||||
user.tour_enabled = user._is_admin() and demo_modules_count == 0 and not modules.module.current_test
|
||||
|
||||
@api.model
|
||||
def switch_tour_enabled(self, val):
|
||||
self.env.user.sudo().tour_enabled = val
|
||||
return self.env.user.tour_enabled
|
||||
|
|
@ -1,30 +1,112 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, fields, models, Command
|
||||
import json
|
||||
import base64
|
||||
|
||||
|
||||
class Tour(models.Model):
|
||||
|
||||
_name = "web_tour.tour"
|
||||
class Web_TourTour(models.Model):
|
||||
_name = 'web_tour.tour'
|
||||
_description = "Tours"
|
||||
_log_access = False
|
||||
_order = "sequence, name, id"
|
||||
|
||||
name = fields.Char(string="Tour name", required=True)
|
||||
user_id = fields.Many2one('res.users', string='Consumed by')
|
||||
name = fields.Char(required=True)
|
||||
step_ids = fields.One2many("web_tour.tour.step", "tour_id")
|
||||
url = fields.Char(string="Starting URL", default="/odoo")
|
||||
sharing_url = fields.Char(compute="_compute_sharing_url", string="Sharing URL")
|
||||
rainbow_man_message = fields.Html(default="<b>Good job!</b> You went through all steps of this tour.", translate=True)
|
||||
sequence = fields.Integer(default=1000)
|
||||
custom = fields.Boolean(string="Custom")
|
||||
user_consumed_ids = fields.Many2many("res.users")
|
||||
|
||||
_uniq_name = models.Constraint(
|
||||
'unique(name)',
|
||||
"A tour already exists with this name . Tour's name must be unique!",
|
||||
)
|
||||
|
||||
@api.depends("name")
|
||||
def _compute_sharing_url(self):
|
||||
for tour in self:
|
||||
tour.sharing_url = f"{tour.get_base_url()}/odoo?tour={tour.name}"
|
||||
|
||||
@api.model
|
||||
def consume(self, tour_names):
|
||||
""" Sets given tours as consumed, meaning that
|
||||
these tours won't be active anymore for that user """
|
||||
if not self.env.user.has_group('base.group_user'):
|
||||
# Only internal users can use this method.
|
||||
# TODO master: update ir.model.access records instead of using sudo()
|
||||
return
|
||||
for name in tour_names:
|
||||
self.sudo().create({'name': name, 'user_id': self.env.uid})
|
||||
def consume(self, tourName):
|
||||
if self.env.user and self.env.user._is_internal():
|
||||
tour_id = self.search([("name", "=", tourName)])
|
||||
if tour_id:
|
||||
tour_id.sudo().user_consumed_ids = [Command.link(self.env.user.id)]
|
||||
return self.get_current_tour()
|
||||
|
||||
@api.model
|
||||
def get_consumed_tours(self):
|
||||
""" Returns the list of consumed tours for the current user """
|
||||
return [t.name for t in self.search([('user_id', '=', self.env.uid)])]
|
||||
def get_current_tour(self):
|
||||
if self.env.user and self.env.user.tour_enabled and self.env.user._is_internal():
|
||||
tours_to_run = self.search([("custom", "=", False), ("user_consumed_ids", "not in", self.env.user.id)])
|
||||
return bool(tours_to_run[:1]) and tours_to_run[:1]._get_tour_json()
|
||||
|
||||
@api.model
|
||||
def get_tour_json_by_name(self, tour_name):
|
||||
tour_id = self.search([("name", "=", tour_name)])
|
||||
return tour_id._get_tour_json()
|
||||
|
||||
def _get_tour_json(self):
|
||||
tour_json = self.read(fields={
|
||||
"name",
|
||||
"url",
|
||||
"custom"
|
||||
})[0]
|
||||
|
||||
del tour_json["id"]
|
||||
tour_json["steps"] = self.step_ids.get_steps_json()
|
||||
tour_json["rainbowManMessage"] = self.rainbow_man_message
|
||||
return tour_json
|
||||
|
||||
def export_js_file(self):
|
||||
js_content = f"""import {{ registry }} from '@web/core/registry';
|
||||
|
||||
registry.category("web_tour.tours").add("{self.name}", {{
|
||||
url: "{self.url}",
|
||||
steps: () => {json.dumps(self.step_ids.get_steps_json(), indent=4)}
|
||||
}})"""
|
||||
|
||||
attachment_id = self.env["ir.attachment"].create({
|
||||
"datas": base64.b64encode(bytes(js_content, 'utf-8')),
|
||||
"name": f"{self.name}.js",
|
||||
"mimetype": "application/javascript",
|
||||
"res_model": "web_tour.tour",
|
||||
"res_id": self.id,
|
||||
})
|
||||
|
||||
return {
|
||||
"type": "ir.actions.act_url",
|
||||
"url": f"/web/content/{attachment_id.id}?download=true",
|
||||
}
|
||||
|
||||
|
||||
class Web_TourTourStep(models.Model):
|
||||
_name = 'web_tour.tour.step'
|
||||
_description = "Tour's step"
|
||||
_order = "sequence, id"
|
||||
|
||||
trigger = fields.Char(required=True)
|
||||
content = fields.Char()
|
||||
tooltip_position = fields.Selection(selection=[
|
||||
["bottom", "Bottom"],
|
||||
["top", "Top"],
|
||||
["right", "Right"],
|
||||
["left", "left"],
|
||||
], default="bottom")
|
||||
tour_id = fields.Many2one("web_tour.tour", required=True, index=True, ondelete="cascade")
|
||||
run = fields.Char()
|
||||
sequence = fields.Integer()
|
||||
|
||||
def get_steps_json(self):
|
||||
steps = []
|
||||
|
||||
for step in self.read(fields=["trigger", "content", "run", "tooltip_position"]):
|
||||
del step["id"]
|
||||
step["tooltipPosition"] = step["tooltip_position"]
|
||||
del step["tooltip_position"]
|
||||
|
||||
if not step["content"]:
|
||||
del step["content"]
|
||||
steps.append(step)
|
||||
|
||||
return steps
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue