diff options
| author | Thibault Delavallée <tde@odoo.com> | 2020-08-20 14:03:52 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2020-08-21 17:30:13 +0000 |
| commit | de8a5652b27da2f659b1378831c6d712ff40b488 (patch) | |
| tree | 0b8f4acaace303f6f0100151bc0e570fb606b530 | |
| parent | 1163013ed6bf191a9e1548866a4df699f72b5bf4 (diff) | |
[REM] website_event_track_session: merge into website_event_track
PURPOSE
Clean organization and models linked to Event Online feature introduced in
semi stable saas-13.3 at odoo/odoo@981f95bbf46658eda9f2d33751b9310cc67d86aa and odoo/enterprise@14722028ae0773c3710ea48ce48ff44703e83b5a
Also clean website event menu not being available in website event but only
in website event track, which implies some extra-code to manage it.
In short: merge website_event_online in website_event, website_event_track
_(online/session) in website_event_track.
RATIONALE
_online modules have been added to extend content of website_event and
website_event_track without having any impact on those module. First step
of cleaning is to move this content directly in base module.
track_session module is mainly a rewrite of track module. Second step of
cleaning is to move its content directly in website_event_track.
SPECIFICATIONS
Move all content of website event track session to website event tracK. It
was mainly of rewriting of views and can now be safely merged into the base
track module.
Update dependencies accordingly.
LINKS
Task ID-2319779
COM odoo/odoo#56067
ENT odoo/enterprise#12520
UPG odoo/upgrade#1654
34 files changed, 901 insertions, 1286 deletions
diff --git a/addons/test_event_full/__manifest__.py b/addons/test_event_full/__manifest__.py index bd0263e341c..8423fc06d7f 100644 --- a/addons/test_event_full/__manifest__.py +++ b/addons/test_event_full/__manifest__.py @@ -21,7 +21,6 @@ automatic lead generation, full Online support, ... 'website_event_sale', 'website_event_track', 'website_event_track_exhibitor', - 'website_event_track_session', 'website_event_track_live', 'website_event_track_quiz', ], diff --git a/addons/website_event_track/controllers/event_track.py b/addons/website_event_track/controllers/event_track.py index e338f384580..782b1e839ee 100644 --- a/addons/website_event_track/controllers/event_track.py +++ b/addons/website_event_track/controllers/event_track.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from ast import literal_eval from datetime import timedelta +from pytz import timezone, utc from werkzeug.exceptions import Forbidden, NotFound import babel @@ -9,13 +11,28 @@ import babel.dates import base64 import pytz -from odoo import exceptions, http, fields +from odoo import exceptions, http, fields, _ from odoo.http import request -from odoo.tools import plaintext2html, html2plaintext +from odoo.osv import expression +from odoo.tools import is_html_empty, plaintext2html class EventTrackController(http.Controller): + def _get_event_tracks_base_domain(self, event): + """ Base domain for displaying tracks. Restrict to accepted or published + tracks for people not managing events. Unpublished tracks may be displayed + but not reachable for teasing purpose. """ + search_domain_base = [ + ('event_id', '=', event.id), + ] + if not request.env.user.has_group('event.group_event_user'): + search_domain_base = expression.AND([ + search_domain_base, + ['|', ('is_published', '=', True), ('is_accepted', '=', True)] + ]) + return search_domain_base + # ------------------------------------------------------------ # TRACK LIST VIEW # ------------------------------------------------------------ @@ -24,27 +41,110 @@ class EventTrackController(http.Controller): '''/event/<model("event.event"):event>/track''', '''/event/<model("event.event"):event>/track/tag/<model("event.track.tag"):tag>''' ], type='http', auth="public", website=True, sitemap=False) - def event_tracks(self, event, tag=None, **post): - if not event.can_access_from_current_website() or (tag and tag.color == 0): + def event_tracks(self, event, tag=None, **searches): + """ Main route + + :param event: event whose tracks are about to be displayed; + :param tag: deprecated: search for a specific tag + :param searches: frontend search dict, containing + + * 'search': search string; + * 'tags': list of tag IDs for filtering; + """ + if not event.can_access_from_current_website(): raise NotFound() + return request.render( + "website_event_track.tracks_session", + self._event_tracks_get_values(event, tag=tag, **searches) + ) + + def _event_tracks_get_values(self, event, tag=None, **searches): + # init and process search terms + searches.setdefault('search', '') + searches.setdefault('search_wishlist', '') + searches.setdefault('tags', '') + search_domain = self._get_event_tracks_base_domain(event) + + # search on content + if searches.get('search'): + search_domain = expression.AND([ + search_domain, + [('name', 'ilike', searches['search'])] + ]) + + # search on tags + search_tags = self._get_search_tags(searches['tags']) + if not search_tags and tag: # backward compatibility + search_tags = tag + if search_tags: + # Example: You filter on age: 10-12 and activity: football. + # Doing it this way allows to only get events who are tagged "age: 10-12" AND "activity: football". + # Add another tag "age: 12-15" to the search and it would fetch the ones who are tagged: + # ("age: 10-12" OR "age: 12-15") AND "activity: football + grouped_tags = dict() + for search_tag in search_tags: + grouped_tags.setdefault(search_tag.category_id, list()).append(search_tag) + search_domain_items = [ + [('tag_ids', 'in', [tag.id for tag in grouped_tags[group]])] + for group in grouped_tags + ] + search_domain = expression.AND([ + search_domain, + *search_domain_items + ]) + + # fetch data to display with TZ set for both event and tracks + now_tz = utc.localize(fields.Datetime.now().replace(microsecond=0), is_dst=False).astimezone(timezone(event.date_tz)) + today_tz = now_tz.date() event = event.with_context(tz=event.date_tz or 'UTC') - searches = {} - if tag: - searches.update(tag=tag.id) - tracks = event.track_ids.filtered(lambda track: tag in track.tag_ids) - else: - tracks = event.track_ids - - values = { + tracks_sudo = event.env['event.track'].sudo().search(search_domain, order='date asc') + tag_categories = request.env['event.track.tag.category'].sudo().search([]) + + # filter on wishlist (as post processing due to costly search on is_reminder_on) + if searches.get('search_wishlist'): + tracks_sudo = tracks_sudo.filtered(lambda track: track.is_reminder_on) + + # organize categories for display: announced, live, soon and day-based + tracks_announced = tracks_sudo.filtered(lambda track: not track.date) + tracks_wdate = tracks_sudo - tracks_announced + date_begin_tz_all = list(set( + dt.date() + for dt in self._get_dt_in_event_tz(tracks_wdate.mapped('date'), event) + )) + date_begin_tz_all.sort() + tracks_sudo_live = tracks_wdate.filtered(lambda track: track.is_published and track.is_track_live) + tracks_sudo_soon = tracks_wdate.filtered(lambda track: track.is_published and not track.is_track_live and track.is_track_soon) + tracks_by_day = [] + for display_date in date_begin_tz_all: + matching_tracks = tracks_wdate.filtered(lambda track: self._get_dt_in_event_tz([track.date], event)[0].date() == display_date) + tracks_by_day.append({'date': display_date, 'name': display_date, 'tracks': matching_tracks}) + if tracks_announced: + tracks_announced = tracks_announced.sorted('wishlisted_by_default', reverse=True) + tracks_by_day.append({'date': False, 'name': _('Coming soon'), 'tracks': tracks_announced}) + + # return rendering values + return { + # event information 'event': event, 'main_object': event, - 'tracks': tracks, - 'tags': event.tracks_tag_ids, + # tracks display information + 'tracks': tracks_sudo, + 'tracks_by_day': tracks_by_day, + 'tracks_live': tracks_sudo_live, + 'tracks_soon': tracks_sudo_soon, + 'today_tz': today_tz, + # search information 'searches': searches, - 'html2plaintext': html2plaintext + 'search_key': searches['search'], + 'search_wishlist': searches['search_wishlist'], + 'search_tags': search_tags, + 'tag_categories': tag_categories, + # environment + 'is_html_empty': is_html_empty, + 'hostname': request.httprequest.host.split(':')[0], + 'user_event_manager': request.env.user.has_group('event.group_event_manager'), } - return request.render("website_event_track.tracks", values) # ------------------------------------------------------------ # AGENDA VIEW @@ -219,14 +319,41 @@ class EventTrackController(http.Controller): # TRACK PAGE VIEW # ------------------------------------------------------------ - @http.route(['''/event/<model("event.event"):event>/track/<model("event.track", "[('event_id','=',event.id)]"):track>'''], type='http', auth="public", website=True, sitemap=True) - def event_track_view(self, event, track, **post): - if not event.can_access_from_current_website(): - raise NotFound() + @http.route('''/event/<model("event.event", "[('website_track', '=', True)]"):event>/track/<model("event.track", "[('event_id', '=', event.id)]"):track>''', + type='http', auth="public", website=True, sitemap=True) + def event_track_page(self, event, track, **options): + track = self._fetch_track(track.id, allow_is_accepted=False) - track = track.sudo().with_context(tz=event.date_tz or 'UTC') - values = {'track': track, 'event': track.event_id, 'main_object': track} - return request.render("website_event_track.track_view", values) + return request.render( + "website_event_track.event_track_main", + self._event_track_page_get_values(event, track.sudo(), **options) + ) + + def _event_track_page_get_values(self, event, track, **options): + track = track.sudo() + + option_widescreen = options.get('widescreen', False) + option_widescreen = bool(option_widescreen) if option_widescreen != '0' else False + # search for tracks list + tracks_other = track._get_track_suggestions( + restrict_domain=self._get_event_tracks_base_domain(track.event_id), + limit=10 + ) + + return { + # event information + 'event': event, + 'main_object': track, + 'track': track, + # sidebar + 'tracks_other': tracks_other, + # options + 'option_widescreen': option_widescreen, + # environment + 'is_html_empty': is_html_empty, + 'hostname': request.httprequest.host.split(':')[0], + 'user_event_manager': request.env.user.has_group('event.group_event_manager'), + } @http.route("/event/track/toggle_reminder", type="json", auth="public", website=True) def track_reminder_toggle(self, track_id, set_reminder_on): @@ -330,3 +457,21 @@ class EventTrackController(http.Controller): raise Forbidden() return track + + def _get_search_tags(self, tag_search): + # TDE FIXME: make me generic (slides, event, ...) + try: + tag_ids = literal_eval(tag_search) + except Exception: + tags = request.env['event.track.tag'].sudo() + else: + # perform a search to filter on existing / valid tags implicitly + tags = request.env['event.track.tag'].sudo().search([('id', 'in', tag_ids)]) + return tags + + def _get_dt_in_event_tz(self, datetimes, event): + tz_name = event.date_tz + return [ + utc.localize(dt, is_dst=False).astimezone(timezone(tz_name)) + for dt in datetimes + ] diff --git a/addons/website_event_track/data/event_track_demo.xml b/addons/website_event_track/data/event_track_demo.xml index 4eeead8b65f..71308eb0736 100644 --- a/addons/website_event_track/data/event_track_demo.xml +++ b/addons/website_event_track/data/event_track_demo.xml @@ -344,6 +344,10 @@ <field name="duration">2</field> <field name="user_id" ref="base.user_admin"/> <field name="partner_id" ref="base.res_partner_address_15"/> + <field name="website_cta" eval="True"/> + <field name="website_cta_title">Try Now</field> + <field name="website_cta_url">http://www.example.com</field> + <field name="website_cta_delay">10</field> </record> <record id="event_7_track_2" model="event.track"> <field name="name">First Day Wrapup</field> @@ -387,6 +391,10 @@ <field name="duration">2</field> <field name="user_id" ref="base.user_admin"/> <field name="partner_id" ref="base.res_partner_address_15"/> + <field name="website_cta" eval="True"/> + <field name="website_cta_title">Try Now</field> + <field name="website_cta_url">http://www.example.com</field> + <field name="website_cta_delay">10</field> </record> <!-- Location 2 --> <record id="event_7_track_5" model="event.track"> diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index 2ec57bddde4..9c44d2d290d 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -2,6 +2,8 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import timedelta +from pytz import utc +from random import randint from odoo import api, fields, models from odoo.addons.http_routing.models.ir_http import slug @@ -78,6 +80,27 @@ class Track(models.Model): date = fields.Datetime('Track Date') date_end = fields.Datetime('Track End Date', compute='_compute_end_date', store=True) duration = fields.Float('Duration', default=1.5, help="Track duration in hours.") + is_track_live = fields.Boolean( + 'Is Track Live', compute='_compute_track_time_data', + help="Track has started and is ongoing") + is_track_soon = fields.Boolean( + 'Is Track Soon', compute='_compute_track_time_data', + help="Track begins soon") + is_track_today = fields.Boolean( + 'Is Track Today', compute='_compute_track_time_data', + help="Track begins today") + is_track_upcoming = fields.Boolean( + 'Is Track Upcoming', compute='_compute_track_time_data', + help="Track is not yet started") + is_track_done = fields.Boolean( + 'Is Track Done', compute='_compute_track_time_data', + help="Track is finished") + track_start_remaining = fields.Integer( + 'Minutes before track starts', compute='_compute_track_time_data', + help="Remaining time before track starts (seconds)") + track_start_relative = fields.Integer( + 'Minutes compare to track start', compute='_compute_track_time_data', + help="Relative time compared to track start (seconds)") # frontend description website_image = fields.Image(string="Website Image", max_width=1024, max_height=1024) website_image_url = fields.Char( @@ -100,6 +123,18 @@ class Track(models.Model): wishlisted_by_default = fields.Boolean( string='Always Wishlisted', help="""If set, the talk will be starred for each attendee registered to the event. The attendee won't be able to un-star this talk.""") + # Call to action + website_cta = fields.Boolean('Magic Button') + website_cta_title = fields.Char('Button Title') + website_cta_url = fields.Char('Button Target URL') + website_cta_delay = fields.Integer('Button appears') + # time information for CTA + is_website_cta_live = fields.Boolean( + 'Is CTA Live', compute='_compute_cta_time_data', + help="CTA button is available") + website_cta_start_remaining = fields.Integer( + 'Minutes before CTA starts', compute='_compute_cta_time_data', + help="Remaining time before CTA starts (seconds)") @api.depends('name') def _compute_website_url(self): @@ -219,12 +254,61 @@ class Track(models.Model): ]) return [('id', 'in', track_visitors.track_id.ids)] + # TIME + + @api.depends('date', 'date_end') + def _compute_track_time_data(self): + """ Compute start and remaining time for track itself. Do everything in + UTC as we compute only time deltas here. """ + now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0)) + for track in self: + if not track.date: + track.is_track_live = track.is_track_soon = track.is_track_today = track.is_track_upcoming = track.is_track_done = False + track.track_start_relative = track.track_start_remaining = 0 + continue + date_begin_utc = utc.localize(track.date, is_dst=False) + date_end_utc = utc.localize(track.date_end, is_dst=False) + track.is_track_live = date_begin_utc <= now_utc < date_end_utc + track.is_track_soon = (date_begin_utc - now_utc).total_seconds() < 30*60 if date_begin_utc > now_utc else False + track.is_track_today = date_begin_utc.date() == now_utc.date() + track.is_track_upcoming = date_begin_utc > now_utc + track.is_track_done = date_end_utc <= now_utc + if date_begin_utc >= now_utc: + track.track_start_relative = int((date_begin_utc - now_utc).total_seconds()) + track.track_start_remaining = track.track_start_relative + else: + track.track_start_relative = int((now_utc - date_begin_utc).total_seconds()) + track.track_start_remaining = 0 + + @api.depends('date', 'date_end', 'website_cta', 'website_cta_delay') + def _compute_cta_time_data(self): + """ Compute start and remaining time for track itself. Do everything in + UTC as we compute only time deltas here. """ + now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0)) + for track in self: + if not track.website_cta: + track.is_website_cta_live = track.website_cta_start_remaining = False + continue + + date_begin_utc = utc.localize(track.date, is_dst=False) + timedelta(minutes=track.website_cta_delay or 0) + date_end_utc = utc.localize(track.date_end, is_dst=False) + track.is_website_cta_live = date_begin_utc <= now_utc <= date_end_utc + if date_begin_utc >= now_utc: + td = date_begin_utc - now_utc + track.website_cta_start_remaining = int(td.total_seconds()) + else: + track.website_cta_start_remaining = 0 + # ------------------------------------------------------------ # CRUD # ------------------------------------------------------------ @api.model_create_multi def create(self, vals_list): + for values in vals_list: + if values.get('website_cta_url'): + values['website_cta_url'] = self.env['res.partner']._clean_website(values['website_cta_url']) + tracks = super(Track, self).create(vals_list) for track in tracks: @@ -239,6 +323,8 @@ class Track(models.Model): return tracks def write(self, vals): + if vals.get('website_cta_url'): + vals['website_cta_url'] = self.env['res.partner']._clean_website(vals['website_cta_url']) if 'stage_id' in vals and 'kanban_state' not in vals: vals['kanban_state'] = 'normal' if vals.get('stage_id'): @@ -317,6 +403,9 @@ class Track(models.Model): 'type': 'ir.actions.act_window', } + def get_backend_menu_id(self): + return self.env.ref('event.event_main_menu').id + # ------------------------------------------------------------ # TOOLS # ------------------------------------------------------------ @@ -352,3 +441,52 @@ class Track(models.Model): } for track in missing]) return track_visitors + + def _get_track_suggestions(self, restrict_domain=None, limit=None): + """ Returns the next tracks suggested after going to the current one + given by self. Tracks always belong to the same event. + + Heuristic is + + * live first; + * then ordered by start date, finished being sent to the end; + * wishlisted (manually or by default); + * tag matching with current track; + * location matching with current track; + * finally a random to have an "equivalent wave" randomly given; + + :param restrict_domain: an additional domain to restrict candidates; + :param limit: number of tracks to return; + """ + self.ensure_one() + + base_domain = [ + '&', + ('event_id', '=', self.event_id.id), + ('id', '!=', self.id), + ] + if restrict_domain: + base_domain = expression.AND([ + base_domain, + restrict_domain + ]) + + track_candidates = self.search(base_domain, limit=None, order='date asc') + if not track_candidates: + return track_candidates + + track_candidates = track_candidates.sorted( + lambda track: + (track.is_published, + track.is_track_live, + track.track_start_remaining > 0, + -1 * track.track_start_remaining, + track.is_reminder_on, + not track.wishlisted_by_default, + len(track.tag_ids & self.tag_ids), + track.location_id == self.location_id, + randint(0, 20), + ), reverse=True + ) + + return track_candidates[:limit] diff --git a/addons/website_event_track_session/static/src/scss/event_track_templates.scss b/addons/website_event_track/static/src/scss/event_track_templates_online.scss index a37a0a380cb..a37a0a380cb 100644 --- a/addons/website_event_track_session/static/src/scss/event_track_templates.scss +++ b/addons/website_event_track/static/src/scss/event_track_templates_online.scss diff --git a/addons/website_event_track/tests/__init__.py b/addons/website_event_track/tests/__init__.py index 12b9da864c8..aac974d7656 100644 --- a/addons/website_event_track/tests/__init__.py +++ b/addons/website_event_track/tests/__init__.py @@ -2,4 +2,5 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import common +from . import test_track_internals from . import test_website_event diff --git a/addons/website_event_track_session/tests/test_track_internals.py b/addons/website_event_track/tests/test_track_internals.py index e2af8c0c6fe..e2af8c0c6fe 100644 --- a/addons/website_event_track_session/tests/test_track_internals.py +++ b/addons/website_event_track/tests/test_track_internals.py diff --git a/addons/website_event_track/views/assets.xml b/addons/website_event_track/views/assets.xml index 120f828839d..c94ee9ece00 100644 --- a/addons/website_event_track/views/assets.xml +++ b/addons/website_event_track/views/assets.xml @@ -5,6 +5,7 @@ <xpath expr="//link[last()]" position="after"> <link rel="stylesheet" href="/website_event_track/static/src/css/website_event_track.css"/> <link rel="stylesheet" type="text/scss" href="/website_event_track/static/src/scss/event_track_templates.scss"/> + <link rel="stylesheet" type="text/scss" href="/website_event_track/static/src/scss/event_track_templates_online.scss"/> <link rel="stylesheet" type="text/scss" href="/website_event_track/static/src/scss/pwa_frontend.scss"/> </xpath> <xpath expr="//script[last()]" position="after"> diff --git a/addons/website_event_track/views/event_track_templates_agenda.xml b/addons/website_event_track/views/event_track_templates_agenda.xml index d7ddf00da0b..1608924587c 100644 --- a/addons/website_event_track/views/event_track_templates_agenda.xml +++ b/addons/website_event_track/views/event_track_templates_agenda.xml @@ -150,6 +150,9 @@ <template id="agenda_main_track" name="Track Agenda: Track"> <div class="d-flex flex-column h-100"> <div class="d-flex justify-content-end flex-wrap-reverse o_weagenda_track_badges"> + <small t-if="track.is_track_live and not track.is_track_done and track.website_published" + class="mx-1 badge badge-danger">Live + </small> <small t-if="not track.website_published and user_event_manager and track.stage_id.is_accepted" title="Unpublished" class="ml-1 badge badge-danger o_wevent_online_badge_unpublished">Unpublished</small> diff --git a/addons/website_event_track/views/event_track_templates_list.xml b/addons/website_event_track/views/event_track_templates_list.xml index 35cdf9d24ca..85059f44c71 100644 --- a/addons/website_event_track/views/event_track_templates_list.xml +++ b/addons/website_event_track/views/event_track_templates_list.xml @@ -1,93 +1,374 @@ <?xml version="1.0" encoding="utf-8"?> <odoo> -<template id="tracks" track="True"> +<template id="tracks_session" name="Event Tracks"> <t t-call="website_event.layout"> - <div class="oe_structure" id="oe_structure_website_event_track_tracks_1"/> - <section class="pt48 pb48"> - <div class="container"> + <div class="o_wevent_online o_wesession_index"> + <!-- Options --> + <t t-set="option_track_wishlist" t-value="not event.is_done and request.website.viewref('website_event_track.session_topbar_wishlist').active"/> + <!-- Topbar --> + <t t-call="website_event_track.session_topbar"/> + <!-- Drag/Drop Area --> + <div id="oe_structure_wesession_index_1" class="oe_structure"/> + <!-- Content --> + <div class="o_wesession_container container"> <div class="row"> - <div id="left_column"> + <t t-call="website_event_track.tracks_search"/> + </div> + <div class="row"> + <t t-call="website_event_track.tracks_main"/> + </div> + </div> + <!-- Drag/Drop Area --> + <div id="oe_structure_wesession_index_2" class="oe_structure mb-5"/> + </div> + </t> +</template> + +<!-- ============================================================ --> +<!-- TOPBAR: BASE NAVIGATION --> +<!-- ============================================================ --> + +<!-- Main topbar --> +<template id="session_topbar" name="Tracks Tools"> + <nav class="navbar navbar-light border-top shadow-sm d-print-none"> + <div class="container"> + <div class="d-flex flex-column flex-sm-row justify-content-between w-100"> + <ul class="o_wesession_topbar_filters o_wevent_index_topbar_filters nav"> + <!-- Optional wishlist filter --> + <li t-if="option_track_wishlist" class="nav-item dropdown mr-2 my-1"> + <a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown"> + <i class="fa fa-folder-open"/> Wishlist + </a> + <div class="dropdown-menu"> + <a t-att-href="'/event/%s/track?%s' % ( + slug(event), + keep_query('*', search_wishlist='') + )" + class="dropdown-item d-flex align-items-center justify-content-between"> + All Talks + </a> + <a t-att-href="'/event/%s/track?%s' % ( + slug(event), + keep_query('*', search_wishlist='1') + )" + t-attf-class="dropdown-item d-flex align-items-center justify-content-between #{'active' if search_wishlist else ''}"> + Wishlisted + </a> + </div> + </li> + </ul> + <div class="d-flex align-items-center flex-wrap pl-sm-3 pr-0"> + <t t-call="website_event.events_search_box"> + <t t-set="_searches" t-value="searches"/> + <t t-set="action" t-value="'/event/%s/track' % (slug(event))"/> + <t t-set="_placeholder" t-value="'Search a talk ...'"/> + </t> + </div> + </div> + </div> + </nav> +</template> + +<!-- Option: Topbar: optional tags filters --> +<template id="session_topbar_tag" + inherit_id="website_event_track.session_topbar" + name="Filter by Tags" + active="True" + customize_show="True"> + <xpath expr="//ul[hasclass('o_wesession_topbar_filters')]" position="inside"> + <t t-foreach="tag_categories" t-as="tag_category"> + <li t-if="tag_category.tag_ids and any(tag.color for tag in tag_category.tag_ids)" class="nav-item dropdown mr-2 my-1"> + <a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown"> + <i class="fa fa-folder-open"/> + <t t-esc="tag_category.name"/> + </a> + <div class="dropdown-menu"> + <t t-foreach="tag_category.tag_ids" t-as="tag"> + <a t-att-href="'/event/%s/track?%s' % ( + slug(event), + keep_query('*', tags=str((search_tags - tag).ids if tag in search_tags else (tag | search_tags).ids)) + )" + t-if="tag.color" + t-attf-class="dropdown-item d-flex align-items-center justify-content-between #{'active' if tag in search_tags else ''}"> + <t t-esc="tag.name"/> + </a> + </t> + </div> + </li> + </t> + </xpath> +</template> + +<!-- Option: Tracks display: optional wishlist --> +<template id="session_topbar_wishlist" + inherit_id="website_event_track.session_topbar" + name="Allow Wishlists" + active="True" + customize_show="True"> + <xpath expr="//ul[hasclass('o_wesession_topbar_filters')]" position="inside"> + </xpath> +</template> + +<!-- ============================================================ --> +<!-- CONTENT: MAIN TEMPLATES --> +<!-- ============================================================ --> + +<!-- Tracks Main Display --> +<template id="tracks_main" name="Tracks: Main Display"> + <!-- No tracks --> + <t t-if="not tracks"> + <div class="col-12"> + <div class="h2 mb-3">No track found.</div> + <div t-if="search_key" class="alert alert-info text-center"> + <p class="m-0">We did not find any track matching your <strong t-esc="search_key"/> search.</p> + </div> + <div t-else="" class="alert alert-info text-center" groups="event.group_event_manager"> + <p class="m-0">Schedule some tracks to get started !</p> + </div> + </div> + </t> + <!-- Cards --> + <div class="col-12" t-call="website_event_track.tracks_display_cards"/> + <!-- List --> + <div class="col-12" t-call="website_event_track.tracks_display_list"/> +</template> + +<!-- Tracks: Cards-based display --> +<template id="tracks_display_cards" name="Tracks: Cards Display"> + <div class="row mb-3" t-if="tracks_live"> + <div class="col-12"> + <h5 class="m-0 text-danger">Live Now</h5> + <hr class="mt-2 pb-1 mb-1"/> + </div> + <div t-foreach="tracks_live" t-as="track" class="col-md-6 col-lg-3 mb-4"> + <t t-call="website_event_track.tracks_cards_track"/> + </div> + </div> + <div class="row mb-3" t-if="tracks_soon"> + <div class="col-12"> + <h5 class="m-0 text-danger">Coming soon ...</h5> + <hr class="mt-2 pb-1 mb-1"/> + </div> + <div t-foreach="tracks_soon" t-as="track" class="col-md-6 col-lg-3 mb-4"> + <t t-call="website_event_track.tracks_cards_track"/> + </div> + </div> +</template> + +<!-- Tracks: List-based display --> +<template id="tracks_display_list" name="Tracks: List Display"> + <div t-if="tracks" class="o_wesession_list mb-3"> + <ul class="list-unstyled"> + <li t-foreach="tracks_by_day" t-as="tracks_info" + class="mb-5"> + <t t-set="tracks_date" t-value="tracks_info['date']"/> + <t t-set="tracks_header_name" t-value="tracks_info['name']"/> + <t t-set="tracks" t-value="tracks_info['tracks']"/> + <!-- DAY HEADER --> + <div class="o_we_track_day_header w-100"> + <div t-if="tracks_date" class="d-flex"> + <span class="h1 m-0 font-weight-bold" t-esc="tracks_date" + t-options="{'widget': 'date', 'format': 'EEEE dd'}"/> + <div class="d-flex flex-column ml-2"> + <span class="font-weight-bold" t-esc="tracks_date" + t-options="{'widget': 'date', 'format': 'MMMM'}"/> + <span class="font-weight-bold" t-esc="tracks_date" + t-options="{'widget': 'date', 'format': 'YYYY'}"/> + </div> + </div> + <div t-elif="tracks_header_name"> + <span class="h1 m-0 font-weight-bold" + t-esc="tracks_header_name"/> </div> - <div class="col-lg-9"> - <div class="alert alert-warning" t-if="not len(tracks)" role="alert"> - No tracks found! + <hr class="mt-2 pb-1 mb-1"/> + </div> + <!-- DAY TRACKS LIST --> + <div t-foreach="tracks" t-as="track" class="row mt8 o_wesession_list_item"> + <div class="col-md-7"> + <span class="h5 mb0"> + <a t-if="track.is_published or user_event_manager" + t-att-href="track.website_url"> + <span t-field="track.name"/> + </a> + <t t-else=""> + <span t-field="track.name"/> + </t> + <span t-if="not track.is_published and user_event_manager" + class="badge badge-danger ml-2 o_wevent_online_badge_unpublished"> + Unpublished + </span> + </span> + <div class="text-muted"> + <span class="text-muted" t-esc="track.partner_name"/> + <t t-if="track.partner_name"> &bull; </t> + <span t-esc="track.duration" + t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'hour', 'round': 'minute'}"/> </div> - <div class="row mb-2" t-foreach="tracks" t-as="track"> - <div class="col-md-2"> - <t t-if="track.image"> - <span t-field="track.image" - t-options='{"widget": "image", "class": "rounded-circle"}'/> + </div> + <div class="col-md-5"> + <div t-if="not event.is_done" class="float-right"> + <t t-if="tracks_date and today_tz <= tracks_date"> + <span t-if="track.is_track_live and not track.is_track_done" + class="badge badge-danger">Live</span> + <span t-elif="not track.is_track_done and track.is_track_soon"> + <span t-esc="track.track_start_remaining" + t-options="{'widget': 'duration', 'digital': False, 'format': 'narrow', + 'add_direction': True, 'unit': 'second', 'round': 'minute'}"/> + </span> + <t t-elif="not track.is_track_done and not track.is_track_soon"> + <span + class="mr-2" + t-esc="track.date" + t-options="{'widget': 'datetime', 'time_only': True, 'format': 'short'}"/> + <t t-if="option_track_wishlist" + t-call="website_event_track.track_widget_reminder"> + <t t-set="reminder_small" t-value="True"/> + </t> + </t> + <t t-else=""> + <span class="badge badge-info">Finished</span> </t> - </div> - <div class="col-md-10"> - <h3 class="mt0 mb0"> - <a t-attf-href="/event/#{ slug(event) }/track/#{ slug(track) }" class="text-secondary"><span t-field="track.name"> </span></a> - <small t-if="not track.website_published" class="badge badge-danger">unpublished</small> - </h3> - <ul class="list-inline mb0"> - <li t-if="track.partner_id" class="list-inline-item"> - <i class="fa fa-user text-primary"/> - <t t-esc="track.partner_id.sudo().name"/> - </li> - <li t-if="track.date" class="list-inline-item"> - <i class="fa fa-calendar text-primary"/> - <span t-field="track.date" t-options='{"hide_seconds":"True"}'/> - </li> - <li class="list-inline-item" t-if="track.location_id"> - <i class="fa fa-map-marker"/> - <span t-field="track.location_id"/> - </li> - </ul> - <ul class="list-inline"> - <li t-foreach="track.tag_ids" t-as="tag_id" class="list-inline-item fa fa-tags" t-if="tag_id.color != 0"> - <a t-attf-href="/event/#{ slug(event) }/track/tag/#{ slug(tag_id) }"> - <i class="fa fa-tags"/> - <span t-field="tag_id.name"/> - </a> - </li> - </ul> - <p class="mt8"><t t-esc="html2plaintext(track.description or '')[0:500]"/><t t-if="track.description">...</t></p> - </div> + </t> + <t t-elif="not track.date and option_track_wishlist" + t-call="website_event_track_online.track_widget_reminder"> + <t t-set="reminder_small" t-value="True"/> + </t> </div> + <t t-foreach="track.tag_ids" t-as="tag"> + <t t-if="tag.color" t-call="website_event_track.track_tag_badge_link"/> + </t> </div> </div> + </li> + </ul> + </div> +</template> + +<!-- ============================================================ --> +<!-- TOOL TEMPLATES --> +<!-- ============================================================ --> + +<template id="tracks_cards_track" name="Track Card"> + <a t-att-href="'/event/%s/track/%s' % (slug(track.event_id), slug(track))" class="text-decoration-none"> + <article t-att-class="'h-100 card border-0 shadow-sm o_wesession_track_card %s' % ('o_wesession_track_card_unpublished' if not track.is_published else '')" + itemscope="itemscope" itemtype="http://schema.org/Event"> + <div class="h-100 row no-gutters"> + <header class="overflow-hidden bg-secondary col-12 rounded-top"> + <small t-if="not track.is_published" class="o_wesession_track_card_header_badge bg-danger"> + <i class="fa fa-ban mr-2"/>Unpublished + </small> + + <div t-if="track.website_image_url" class="card-img-top" + t-attf-style="padding-top: 50%; background-image: url(#{track.website_image_url}); background-size: cover; background-position:center"> + <span t-if="option_track_wishlist and not track.is_track_live" class="position-absolute h3 mt-2 mr-2" style="right: 0; top: 0;"> + <t t-call="website_event_track.track_widget_reminder"> + <t t-set="reminder_light" t-value="True"/> + <t t-set="light_theme" t-value="True"/> + </t> + </span> + </div> + <div t-else="" class="o_wesession_gradient card-img-top position-relative" + style="padding-top: 50%;"> + <span t-if="option_track_wishlist" class="position-absolute h3 mt-2 mr-2" style="right: 0; top: 0;"> + <t t-call="website_event_track.track_widget_reminder"> + <t t-set="reminder_light" t-value="True"/> + </t> + </span> + <i class="fa fa-glass fa-2x mx-2 mb-3 position-absolute text-white-75" style="right:0; bottom: 0;"/> + </div> + </header> + <div class="col-12"> + <main class="card-body"> + <!-- Title --> + <h5 class="card-title mt-0 mb-0 text-truncate"> + <span t-field="track.name" itemprop="name"/> + </h5> + <!-- Tags> --> + <div> + <t t-foreach="track.tag_ids" t-as="tag"> + <t t-if="tag.color" t-call="website_event_track.track_tag_badge_info"/> + </t> + </div> + </main> + </div> + <!-- Footer --> + <footer class="small align-self-end w-100 card-footer"> + <div class="d-flex justify-content-between align-items-center"> + <!-- Speaker --> + <span class="text-muted text-truncate" t-field="track.partner_name" itemprop="performer"/> + <!-- Starts --> + <span class="text-muted ml-auto"> + <t t-if="track.is_track_upcoming > 0">In + <span class="text-muted ml-auto" t-field="track.track_start_remaining" itemprop="duration" + t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'second', 'round': 'minute'}"/> + </t> + <t t-else=""> + <span class="text-muted ml-auto" t-field="track.track_start_relative" itemprop="duration" + t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'second', 'round': 'minute'}"/> + ago + </t> + </span> + </div> + </footer> </div> - </section> - <div class="oe_structure" id="oe_structure_website_event_track_tracks_2"/> - </t> + </article> + </a> </template> -<template id="tracks_filter" inherit_id="website_event_track.tracks" customize_show="True" name="Filter on Tags"> - <xpath expr="//div[@id='left_column']" position="inside"> - <ul class="nav nav-pills flex-column"> - <li class="nav-item"><a t-attf-href="/event/#{ slug(event) }/track" t-attf-class="nav-link #{'' if searches.get('tag') else ' active'}">All Tags</a></li> - <t t-foreach="tags" t-as="tag"> - <li class="nav-item"> - <a t-attf-href="/event/#{ slug(event) }/track/tag/#{ slug(tag) }" t-attf-class="nav-link#{searches.get('tag') == tag.id and ' active' or ''}"> - <t t-esc="tag.name"/> - </a> - </li> - </t> - </ul> - </xpath> - <xpath expr="//div[@id='left_column']" position="attributes"> - <attribute name="class">col-lg-3 css_no_print</attribute> - </xpath> +<!-- Searched tags --> +<template id="tracks_search" name="Tracks: search tags"> + <div class="d-flex align-items-center mb-3"> + <span t-if="search_wishlist" + class="align-items-baseline border d-inline-flex pl-2 mt-3 rounded ml16 mb-2 bg-white"> + <i class="fa fa-bell mr-2 text-muted"/> Wishlisted Talks + <a t-att-href="'/event/%s/track?%s' % (slug(event), keep_query('*', search_wishlist=''))" + class="btn border-0 py-1"> + × + </a> + </span> + + <t t-foreach="search_tags" t-as="tag"> + <span class="align-items-baseline border d-inline-flex pl-2 mt-3 rounded ml16 mb-2 bg-white"> + <i class="fa fa-tag mr-2 text-muted"/> + <t t-esc="tag.display_name"/> + <a t-att-href="'/event/%s/track?%s' % (slug(event), keep_query('*', tags=str((search_tags - tag).ids)))" + class="btn border-0 py-1"> + × + </a> + </span> + </t> + </div> </template> -<!-- Add wishlist button on tracks / track templates --> -<template id="tracks_wishlist" - name="Wishlist on Tracks" - inherit_id="website_event_track.tracks" - customize_show="True"> - <xpath expr="//h3" position="replace"> - <h3 class="mt0 mb0 d-flex"> - <a t-attf-href="/event/#{ slug(event) }/track/#{ slug(track) }" class="text-secondary"><span t-field="track.name"> </span></a> - <small t-if="not track.website_published" class="badge badge-danger">unpublished</small> - <t t-call="website_event_track.track_widget_reminder"/> - </h3> - </xpath> +<!-- ============================================================ --> +<!-- MISC TOOLS --> +<!-- ============================================================ --> + +<template id="track_tag_badge_link" name="Track: Tag Badge Link"> + <a t-if="search_tags" + t-att-href="'/event/%s/track?%s'% ( + slug(event), + keep_query('*', tags=str((search_tags - tag).ids if tag in search_tags else (tag | search_tags).ids)) + )" + t-att-class="'badge %s' % ('badge-primary' if tag in search_tags else 'o_tag_color_hovered_0')" + t-esc="tag.name"/> + <a t-else="" + t-att-href="'/event/%s/track?%s'% ( + slug(event), + keep_query('*', tags=str(tag.ids)) + )" + t-att-class="'badge o_tag_color_hovered_%s' % (tag.color)" + t-esc="tag.name"/> +</template> + +<template id="track_tag_badge_info" name="Track: Tag Badge Info"> + <span t-if="search_tags" + t-att-class="'badge %s' % ('badge-primary' if tag in search_tags else 'o_tag_color_0')" + t-esc="tag.name"/> + <span t-else="" + t-att-class="'badge o_tag_color_%s' % (tag.color)" + t-esc="tag.name"/> </template> </odoo> diff --git a/addons/website_event_track/views/event_track_templates_page.xml b/addons/website_event_track/views/event_track_templates_page.xml index 5d4b5617b29..c8cbed11e45 100644 --- a/addons/website_event_track/views/event_track_templates_page.xml +++ b/addons/website_event_track/views/event_track_templates_page.xml @@ -1,99 +1,216 @@ <?xml version="1.0" encoding="utf-8"?> <odoo> -<template id="track_view" track="True"> +<template id="event_track_main" name="Event Exhibitor"> <t t-call="website_event.layout"> - <section class="pt48"> - <div class="container"> - <div class="row"> - <div class="col-12"> - <h1 t-field="track.name"/> - <small>Proposed by - <span t-if="track.partner_id" t-field="track.partner_id.sudo().name"/> - <span t-if="not track.partner_id" t-field="track.partner_name"/> - </small> - <ul t-if="track.tag_ids" class="text-center text-muted list-inline"> - <li t-foreach="track.tag_ids" t-as="tag_id" class="list-inline-item" t-if="tag_id.color != 0"> - <span class="fa fa-tags"></span> - <a t-attf-href="/event/#{ slug(event) }/track/tag/#{ slug(tag_id) }"> - <span t-field="tag_id.name"/> - </a> - </li> - </ul> - </div> + <div class="o_wevent_online o_wevent_online_bg o_wesession_index"> + <!-- Options --> + <t t-set="option_widescreen" t-value="option_widescreen or False"/> + <t t-set="option_track_wishlist" t-value="not event.is_done and request.website.viewref('website_event_track.session_topbar_wishlist').active"/> + <!-- Drag/Drop Area --> + <div id="oe_structure_wesession_track_index_1" class="oe_structure"/> + <!-- Content --> + <div t-att-class="'o_wevent_online_page_container %s' % ('container pb-3' if not option_widescreen else 'pb-3')"> + <div class="row mb-5 mx-0"> + <t t-call="website_event_track.event_track_aside"/> + <t t-call="website_event_track.event_track_content"/> </div> </div> - </section> - <section class="pt32"> - <div class="container"> - <div class="row"> - <div class="col-lg-8"> - <div t-field="track.description"/> - <h3>About The Speaker</h3> - <div t-field="track.partner_biography"/> - <div t-if="track.partner_id" class="row mt32"> - <div class="col-md-2"> - <span t-if="track.image" t-field="track.image" t-options="{'widget': 'image', 'class': 'rounded-circle'}"/> - <span t-else="" t-field="track.partner_id.sudo().image_128" t-options='{"widget": "image", "class": "rounded-circle"}'/> - </div> - <div class="col-md-10"> - <h4 t-field="track.partner_id.name" class="mb4"/> - <div class="mb16" t-if="track.partner_id.website"> - <i class="fa fa-home mr-2"/><a t-att-href="track.partner_id.website"><span t-field="track.partner_id.website"/></a> - </div> - <div t-field="track.partner_id.website_description"/> - </div> - </div> + <!-- Drag/Drop Area --> + <div id="oe_structure_wesession_track_index_2" class="oe_structure"/> + </div> + </t> +</template> + +<!-- ============================================================ --> +<!-- CONTENT: MAIN TEMPLATES --> +<!-- ============================================================ --> + +<template id="event_track_content" name="Track: Main Description"> + <div name="o_wesession_track_main" + t-att-class="'col-12 o_wevent_online_page_main o_wesession_track_main bg-white p-0 %s' % ('col-md-9 col-lg-10' if option_widescreen else 'col-md-8 col-lg-9')"> + <!-- LIVE INFORMATIONS --> + <div t-if="not track.event_id.is_ongoing" class="pt-3"> + <div class="mx-3 alert alert-warning"> + Event <span t-esc="track.event_id.name" class="font-weight-bold"/> + <span t-if="track.event_id.start_today"> + starts in + <span t-esc="track.event_id.start_remaining" + t-options="{'widget': 'duration', 'digital': False, 'unit': 'minute', 'round': 'minute'}"/> + </span> + <span t-else=""> + starts at + <span t-field="track.event_id.with_context(tz=track.event_id.date_tz).date_begin" + t-options="{'format': 'long', 'tz_name': track.event_id.date_tz, 'hide_seconds': True}"/> + </span> + </div> + </div> + <div t-elif="track.track_start_remaining" class="pt-3"> + <div class="mx-3 alert alert-warning"> + Starting in + <span t-esc="track.track_start_remaining" + t-options="{'widget': 'duration', 'digital': False, 'unit': 'second', 'round': 'minute'}"/> + </div> + </div> + <!-- TRACK DESCRIPTION --> + <div class="o_wesession_track_main_description"> + <div class="mx-3 pt-3 mb-3 d-flex justify-content-between flex-column flex-md-row"> + <div class="d-flex flex-column"> + <span class="h4 mb-0" t-esc="track.name"/> + <div> + <t t-foreach="track.tag_ids" t-as="tag"> + <span t-if="tag.color" + t-att-class="'badge o_tag_color_hovered_%s' % (tag.color)" + t-esc="tag.name"/> + </t> </div> - <div class="col-lg-4" id="right_column"> - <div class="card"> - <h4 class="card-header">Practical Info</h4> - <div class="card-body"> - <b>Date</b><br/> - <t t-if="track.date"> - <span t-field="track.date" t-options='{"hide_seconds":"True", "format": "short"}'/> - <t t-if="event.date_tz"> - (<span t-field="track.date" t-options='{"format": "zzz"}'/>) - </t> - </t> - <t t-else=""> - <span>To be scheduled</span> - </t> - <br/> - <b>Duration</b><br/> - <span t-field="track.duration" t-options='{"widget": "duration", "unit": "hour", "round": "minute"}'/><br/> - <b>Location</b><br/> - <span t-field="track.location_id"/><br/> - </div> + </div> + <div class="o_we_track_action_buttons d-flex justify-content-md-end align-items-center flex-wrap"> + <div class="o_we_track_reminder_button my-1"> + <div t-if="option_track_wishlist and not track.is_track_done" + t-call="website_event_track.track_widget_reminder"> + <t t-set="reminder_small" t-value="False"/> + <t t-set="reminder_light" t-value="False"/> </div> + </div> + </div> + </div> + <div class="mx-3 text-muted"> + <t t-if="track.location_id"> + <strong>Location:</strong> <span t-field="track.location_id"/> + <span> - </span> + </t> + <t t-if="track.date"> + <span t-field="track.date" + t-options='{"hide_seconds":"True", "format": "short"}'/> + - + <span t-field="track.date_end" + t-options='{"hide_seconds":"True", "format": "short"}'/> + <t t-if="event.date_tz"> + (<span t-field="track.date_end" t-options='{"format": "zzz"}'/>) + </t> + </t> + <t t-if="track.duration"> + (<span t-field="track.duration" + t-options='{"widget": "duration", "unit": "hour", "round": "minute"}'/>) + </t> + </div> + + <hr class="mt-2 mb-0"/> - <div class="card" t-if="False"> - <h4 class="card-header">Documents</h4> - <div class="card-body"> - Put here the list of documents, like slides of - the presentations. Remove the above t-if when - it's implemented. - </div> - </div> + <!-- ABOUT AUTHOR --> + <div class="mx-3"> + <div class="mt-2 d-flex"> + <span t-if="track.image" t-field="track.image" class="o_wevent_online_page_avatar" + t-options="{'widget': 'image', 'class': 'rounded-circle', 'max_width': '96'}"/> + <div class="pl-2 pr-0 pr-md-2 d-flex flex-column"> + <span t-field="track.partner_name" class="font-weight-bold mb-2"/> + <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_function"> + <i class="fa fa-briefcase mr-2"/><span t-esc="track.partner_function"/> + <t t-if="track.partner_company_name"> + <span>&nbsp;at&nbsp;</span><span t-esc="track.partner_company_name"/> + </t> + </span> + <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_id.website"> + <i class="fa fa-home mr-2"/><a t-att-href="track.partner_id.website"><span t-field="track.partner_id.website"/></a> + </span> + <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_email"> + <i class="fa fa-envelope mr-2"/><a t-att-mailto="track.partner_email"><span t-field="track.partner_email"/></a> + </span> + <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_phone"> + <i class="fa fa-phone mr-2"/><span t-field="track.partner_phone"/> + </span> </div> </div> + <div t-field="track.partner_biography" class="oe_no_empty"/> + <hr t-if="not is_html_empty(track.description)" class="mt-2 pb-1 mb-1"/> </div> - </section> - </t> + <div t-field="track.description" class="my-2 mx-3 oe_no_empty"/> + </div> + </div> +</template> + +<!-- ============================================================ --> +<!-- ASIDE: CONTROL PANEL --> +<!-- ============================================================ --> + +<template id="event_track_aside" name="Track: Aside"> + <div t-att-class="'col-12 pl-0 pr-0 pr-md-3 o_wevent_online_page_aside o_wesession_track_aside %s' % ('col-md-3 col-lg-2' if option_widescreen else 'col-md-4 col-lg-3')"> + <div class="bg-white pt-0 pt-md-3 o_wevent_online_page_aside_content"> + <div class="mx-2" t-if="track.website_cta"> + <t t-set="cta_coundown" t-value="bool(track.website_cta_start_remaining)"/> + <div t-if="cta_coundown" class="text-center mt-2 mt-md-0 w-100 btn btn-primary d-none"> + <t t-call="website_event.display_timer_widget"> + <t t-set="pre_remaining_time" t-value="int(track.track_start_remaining)"/> + <!--<t t-set="pre_countdown_text" t-value="'Talk starts in'"/>--> + <t t-set="pre_countdown_display" t-value="bool(False)"/> + <t t-set="main_remaining_time" t-value="int(track.website_cta_start_remaining)"/> + <!--<t t-set="main_countdown_text" t-value="'Magic happens in'"/>--> + <t t-set="main_countdown_display" t-value="bool(False)"/> + <t t-set="display_class" t-value="'.o_event_cta_action'"/> + </t> + </div> + <div t-att-class="'o_event_cta_action %s' % ('d-none' if cta_coundown else '')"> + <a t-att-href="track.website_cta_url" + target="_blank" + class="btn btn-primary w-100 mb-3 mt-2 mt-md-0"> + <span t-esc="track.website_cta_title"/> + </a> + </div> + </div> + <div class="d-flex align-items-center justify-content-between mx-2"> + <ul class="nav nav-tabs o_wesession_track_aside_nav d-flex border-0" role="tablist"> + <li class="nav-item flex-grow-1"> + <a href="#track_list" aria-controls="track_list" class="nav-link active" role="tab" data-toggle="tab"> + Talks + </a> + </li> + </ul> + <a href="#collapse_track_aside" data-toggle="collapse" class="d-md-none p-2 text-decoration-none o_wevent_online_page_aside_collapse collapsed"> + <i class="fa fa-chevron-down d-md-none"/> + </a> + </div> + <div id="collapse_track_aside" + class="tab-content collapse d-md-block o_wesession_track_aside_tabs"> + <div class="tab-pane fade show active" id="track_list" role="tabpanel"> + <ul class="list-unstyled mb-0"> + <li t-foreach="tracks_other" t-as="track_other" class="w-100"> + <a t-if="user_event_manager or track_other.is_published" + class="d-block w-100 h-100 px-2 pt-2 pb-1 text-decoration-none" + t-att-href="track_other.website_url"> + <t t-call="website_event_track.event_track_aside_other_track"/> + </a> + <div t-else="" class="text-muted px-2 pt-2 pb-1"> + <t t-call="website_event_track.event_track_aside_other_track"/> + </div> + </li> + </ul> + </div> + </div> + </div> + </div> </template> -<template id="track_view_wishlist" - name="Wishlist on Track" - inherit_id="website_event_track.track_view" - customize_show="True"> - <xpath expr="//h1" position="replace"> - <div class="d-flex"> - <h1 t-field="track.name"/> - <div class="ml-2 pt-1"> - <t t-call="website_event_track.track_widget_reminder"/> +<template id="event_track_aside_other_track"> + <span t-esc="track_other.name" class="w-100"/> + <div class="d-flex align-items-center"> + <small class="text-muted" t-esc="track_other.partner_name"/> + <div class="d-inline-block ml-auto o_wesession_track_aside_info text-truncate"> + <small t-if="track_other.is_track_live and not track_other.is_track_done" + class="badge badge-danger">Live</small> + <small t-elif="track_other.is_track_done" + class="badge badge-light">Done</small> + <small t-elif="track_other.is_track_today and track_other.track_start_remaining" + class="badge badge-light"> + <span t-esc="track_other.track_start_remaining" + t-options="{'widget': 'duration', 'digital': False, 'add_direction': True, + 'unit': 'second', 'round': 'minute', 'format': 'narrow'}"/> + </small> + <div t-elif="track_other.date" class="badge badge-light"> + <span t-esc="track_other.date" t-options="{'widget': 'datetime', 'tz_name': track_other.event_id.date_tz, 'format': 'MMM. dd'}"/> </div> </div> - </xpath> + </div> </template> </odoo> diff --git a/addons/website_event_track/views/event_track_views.xml b/addons/website_event_track/views/event_track_views.xml index 3ff98ac1132..58ff291a2a4 100644 --- a/addons/website_event_track/views/event_track_views.xml +++ b/addons/website_event_track/views/event_track_views.xml @@ -183,6 +183,25 @@ <page string="Description" name="description"> <field name="description"/> </page> + <page string="Interactivity" name="interactivity"> + <group> + <group name="event_track_cta_group"> + <field name="website_cta"/> + <field name="website_cta_title" placeholder="e.g. Get Yours Now !" + attrs="{'invisible': [('website_cta', '=', False)], + 'required': [('website_cta', '=', True)]}"/> + <field name="website_cta_url" placeholder="e.g. http://www.example.com" + attrs="{'invisible': [('website_cta', '=', False)], + 'required': [('website_cta', '=', True)]}"/> + <label for="website_cta_delay" + attrs="{'invisible': [('website_cta', '=', False)]}"/> + <div attrs="{'invisible': [('website_cta', '=', False)]}"> + <field name="website_cta_delay" class="oe_inline" + attrs="{'required': [('website_cta', '=', True)]}"/> minutes after talk start + </div> + </group> + </group> + </page> </notebook> </sheet> <div class="oe_chatter"> diff --git a/addons/website_event_track_live/__manifest__.py b/addons/website_event_track_live/__manifest__.py index 3574deefbc9..be28bb71b0b 100644 --- a/addons/website_event_track_live/__manifest__.py +++ b/addons/website_event_track_live/__manifest__.py @@ -12,7 +12,6 @@ 'description': "", 'depends': [ 'website_event_track', - 'website_event_track_session', ], 'data': [ 'views/assets.xml', diff --git a/addons/website_event_track_live/controllers/session.py b/addons/website_event_track_live/controllers/session.py index 9d6381e6300..ea8cc5411a4 100644 --- a/addons/website_event_track_live/controllers/session.py +++ b/addons/website_event_track_live/controllers/session.py @@ -3,11 +3,11 @@ import re -from odoo.addons.website_event_track_session.controllers.session import WebsiteEventSessionController +from odoo.addons.website_event_track.controllers.event_track import EventTrackController from odoo.http import request -class WebsiteEventSessionLiveController(WebsiteEventSessionController): +class WebsiteEventSessionLiveController(EventTrackController): def _event_track_page_get_values(self, event, track, **options): if 'widescreen' not in options: diff --git a/addons/website_event_track_live/views/event_track_templates_list.xml b/addons/website_event_track_live/views/event_track_templates_list.xml index 9f6236b6bfb..844620dd44f 100644 --- a/addons/website_event_track_live/views/event_track_templates_list.xml +++ b/addons/website_event_track_live/views/event_track_templates_list.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <odoo> -<template id="tracks_display_list" inherit_id="website_event_track_session.tracks_display_list"> +<template id="tracks_display_list" inherit_id="website_event_track.tracks_display_list"> <!-- TRACK LIST: ADD REPLAY TAG FOR FINISHED TRACKS --> <xpath expr="//div[hasclass('o_wesession_list_item')]/div[hasclass('col-md-5')]//t[@t-elif='not track.is_track_done and not track.is_track_soon']" position="after"> <a t-elif="track.youtube_video_url and (track.is_published or user_event_manager)" diff --git a/addons/website_event_track_live/views/event_track_templates_page.xml b/addons/website_event_track_live/views/event_track_templates_page.xml index f72152f6e71..1ac7dfd2748 100644 --- a/addons/website_event_track_live/views/event_track_templates_page.xml +++ b/addons/website_event_track_live/views/event_track_templates_page.xml @@ -2,7 +2,7 @@ <odoo> <!-- MAIN: REMOVE HEADER/FOOTER IF WIDESCREEN --> -<template id="event_track_main" inherit_id="website_event_track_session.event_track_main"> +<template id="event_track_main" inherit_id="website_event_track.event_track_main"> <xpath expr="//t[@t-call='website_event.layout']" position="before"> <t t-set="no_header" t-value="option_widescreen"/> <t t-set="no_footer" t-value="option_widescreen"/> @@ -10,7 +10,7 @@ </template> <!-- MAIN: ADD VIDEO --> -<template id="event_track_content" inherit_id="website_event_track_session.event_track_content"> +<template id="event_track_content" inherit_id="website_event_track.event_track_content"> <!-- Do not display "starting in" in case of replay mode as video is already available --> <xpath expr="//div[@t-elif='track.track_start_remaining']" position="attributes"> <attribute name="t-elif">track.track_start_remaining and not track.is_youtube_replay</attribute> @@ -31,7 +31,7 @@ </template> <!-- ASIDE: ADD CHAT TAB FOR VIDEOS --> -<template id="event_track_aside" inherit_id="website_event_track_session.event_track_aside"> +<template id="event_track_aside" inherit_id="website_event_track.event_track_aside"> <xpath expr="//ul[hasclass('o_wesession_track_aside_nav')]" position="inside"> <li t-if="track.is_youtube_chat_available and not is_mobile_chat_disabled" class="nav-item flex-grow-1"> <a href="#track_chat" aria-controls="track_chat" class="nav-link" role="tab" data-toggle="tab"> diff --git a/addons/website_event_track_quiz/__manifest__.py b/addons/website_event_track_quiz/__manifest__.py index 4aaacbe69f4..e1e71980282 100644 --- a/addons/website_event_track_quiz/__manifest__.py +++ b/addons/website_event_track_quiz/__manifest__.py @@ -12,7 +12,7 @@ 'description': "", 'depends': [ 'website_profile', - 'website_event_track_session', + 'website_event_track', ], 'data': [ 'security/ir.model.access.csv', diff --git a/addons/website_event_track_quiz/controllers/event_track_quiz.py b/addons/website_event_track_quiz/controllers/event_track_quiz.py index 2942313a680..f734952d147 100644 --- a/addons/website_event_track_quiz/controllers/event_track_quiz.py +++ b/addons/website_event_track_quiz/controllers/event_track_quiz.py @@ -2,11 +2,11 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import http -from odoo.addons.website_event_track_session.controllers.session import WebsiteEventSessionController +from odoo.addons.website_event_track.controllers.event_track import EventTrackController from odoo.http import request -class WebsiteEventTrackQuiz(WebsiteEventSessionController): +class WebsiteEventTrackQuiz(EventTrackController): # QUIZZES IN PAGE # ---------------------------------------------------------- diff --git a/addons/website_event_track_quiz/views/event_track_templates_page.xml b/addons/website_event_track_quiz/views/event_track_templates_page.xml index e448cfd35dc..2a50df5e61c 100644 --- a/addons/website_event_track_quiz/views/event_track_templates_page.xml +++ b/addons/website_event_track_quiz/views/event_track_templates_page.xml @@ -3,7 +3,7 @@ <template id="event_track_content" name="Track: Main Description: add quiz" - inherit_id="website_event_track_session.event_track_content"> + inherit_id="website_event_track.event_track_content"> <xpath expr="//div[hasclass('o_wesession_track_main_description')]" position="after"> <div id="we_track_quiz_container" t-if="track.quiz_id" t-att-class="'o_quiz_js_quiz_container o_quiz_main border-top bg-white px-2 pt-4 pb-4 col-12 %s' % ('' if track.is_quiz_completed else 'd-none')" diff --git a/addons/website_event_track_quiz/views/event_track_views.xml b/addons/website_event_track_quiz/views/event_track_views.xml index d8d2f190735..13a0ceac999 100644 --- a/addons/website_event_track_quiz/views/event_track_views.xml +++ b/addons/website_event_track_quiz/views/event_track_views.xml @@ -3,7 +3,7 @@ <record id="event_track_view_form" model="ir.ui.view" > <field name="name">event.track.view.form.inherit.event.track.quiz</field> <field name="model">event.track</field> - <field name="inherit_id" ref="website_event_track_session.event_track_view_form"/> + <field name="inherit_id" ref="website_event_track.view_event_track_form"/> <field name="arch" type="xml"> <xpath expr="//group[@name='event_track_cta_group']" position="after"> <group name="event_track_quiz_group"> diff --git a/addons/website_event_track_session/__init__.py b/addons/website_event_track_session/__init__.py deleted file mode 100644 index 5a31f331a2a..00000000000 --- a/addons/website_event_track_session/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import controllers -from . import models -from . import tests diff --git a/addons/website_event_track_session/__manifest__.py b/addons/website_event_track_session/__manifest__.py deleted file mode 100644 index 5d012021c15..00000000000 --- a/addons/website_event_track_session/__manifest__.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - - -{ - 'name': 'Event Live Sessions', - 'category': 'Marketing/Events', - 'sequence': 1005, - 'version': '1.0', - 'summary': 'Event: live session on tracks', - 'website': 'https://www.odoo.com/page/events', - 'description': "", - 'depends': [ - 'website_event_track', - ], - 'data': [ - 'views/assets.xml', - 'views/event_track_templates_agenda.xml', - 'views/event_track_templates_list.xml', - 'views/event_track_templates_misc.xml', - 'views/event_track_templates_page.xml', - 'views/event_track_views.xml', - ], - 'demo': [ - 'data/event_track_demo.xml', - ], - 'application': False, - 'installable': True, -} diff --git a/addons/website_event_track_session/controllers/__init__.py b/addons/website_event_track_session/controllers/__init__.py deleted file mode 100644 index 1c2ee57c54f..00000000000 --- a/addons/website_event_track_session/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import session diff --git a/addons/website_event_track_session/controllers/session.py b/addons/website_event_track_session/controllers/session.py deleted file mode 100644 index a59e0e500eb..00000000000 --- a/addons/website_event_track_session/controllers/session.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from ast import literal_eval -from pytz import timezone, utc -from werkzeug.exceptions import NotFound - -from odoo import fields, http, _ -from odoo.addons.website_event_track.controllers.event_track import EventTrackController -from odoo.http import request -from odoo.osv import expression -from odoo.tools import is_html_empty - - -class WebsiteEventSessionController(EventTrackController): - - def _get_event_tracks_base_domain(self, event): - """ Base domain for displaying tracks. Restrict to accepted or published - tracks for people not managing events. Unpublished tracks may be displayed - but not reachable for teasing purpose. """ - search_domain_base = [ - ('event_id', '=', event.id), - ] - if not request.env.user.has_group('event.group_event_user'): - search_domain_base = expression.AND([ - search_domain_base, - ['|', ('is_published', '=', True), ('is_accepted', '=', True)] - ]) - return search_domain_base - - # ------------------------------------------------------------ - # MAIN PAGE - # ------------------------------------------------------------ - - @http.route([ - '''/event/<model("event.event", "[('website_track', '=', True)]"):event>/track''', - '''/event/<model("event.event", "[('website_track', '=', True)]"):event>/track/tag/<model("event.track.tag"):tag>''' - ], type='http', auth="public", website=True, sitemap=False) - def event_tracks(self, event, tag=None, **searches): - """ Main route - - :param event: event whose tracks are about to be displayed; - :param tag: deprecated: search for a specific tag - :param searches: frontend search dict, containing - - * 'search': search string; - * 'tags': list of tag IDs for filtering; - """ - if not event.can_access_from_current_website(): - raise NotFound() - - return request.render( - "website_event_track.tracks", - self._event_tracks_get_values(event, tag=tag, **searches) - ) - - def _event_tracks_get_values(self, event, tag=None, **searches): - # init and process search terms - searches.setdefault('search', '') - searches.setdefault('search_wishlist', '') - searches.setdefault('tags', '') - search_domain = self._get_event_tracks_base_domain(event) - - # search on content - if searches.get('search'): - search_domain = expression.AND([ - search_domain, - [('name', 'ilike', searches['search'])] - ]) - - # search on tags - search_tags = self._get_search_tags(searches['tags']) - if not search_tags and tag: # backward compatibility - search_tags = tag - if search_tags: - # Example: You filter on age: 10-12 and activity: football. - # Doing it this way allows to only get events who are tagged "age: 10-12" AND "activity: football". - # Add another tag "age: 12-15" to the search and it would fetch the ones who are tagged: - # ("age: 10-12" OR "age: 12-15") AND "activity: football - grouped_tags = dict() - for search_tag in search_tags: - grouped_tags.setdefault(search_tag.category_id, list()).append(search_tag) - search_domain_items = [ - [('tag_ids', 'in', [tag.id for tag in grouped_tags[group]])] - for group in grouped_tags - ] - search_domain = expression.AND([ - search_domain, - *search_domain_items - ]) - - # fetch data to display with TZ set for both event and tracks - now_tz = utc.localize(fields.Datetime.now().replace(microsecond=0), is_dst=False).astimezone(timezone(event.date_tz)) - today_tz = now_tz.date() - event = event.with_context(tz=event.date_tz or 'UTC') - tracks_sudo = event.env['event.track'].sudo().search(search_domain, order='date asc') - tag_categories = request.env['event.track.tag.category'].sudo().search([]) - - # filter on wishlist (as post processing due to costly search on is_reminder_on) - if searches.get('search_wishlist'): - tracks_sudo = tracks_sudo.filtered(lambda track: track.is_reminder_on) - - # organize categories for display: announced, live, soon and day-based - tracks_announced = tracks_sudo.filtered(lambda track: not track.date) - tracks_wdate = tracks_sudo - tracks_announced - date_begin_tz_all = list(set( - dt.date() - for dt in self._get_dt_in_event_tz(tracks_wdate.mapped('date'), event) - )) - date_begin_tz_all.sort() - tracks_sudo_live = tracks_wdate.filtered(lambda track: track.is_published and track.is_track_live) - tracks_sudo_soon = tracks_wdate.filtered(lambda track: track.is_published and not track.is_track_live and track.is_track_soon) - tracks_by_day = [] - for display_date in date_begin_tz_all: - matching_tracks = tracks_wdate.filtered(lambda track: self._get_dt_in_event_tz([track.date], event)[0].date() == display_date) - tracks_by_day.append({'date': display_date, 'name': display_date, 'tracks': matching_tracks}) - if tracks_announced: - tracks_announced = tracks_announced.sorted('wishlisted_by_default', reverse=True) - tracks_by_day.append({'date': False, 'name': _('Coming soon'), 'tracks': tracks_announced}) - - # return rendering values - return { - # event information - 'event': event, - 'main_object': event, - # tracks display information - 'tracks': tracks_sudo, - 'tracks_by_day': tracks_by_day, - 'tracks_live': tracks_sudo_live, - 'tracks_soon': tracks_sudo_soon, - 'today_tz': today_tz, - # search information - 'searches': searches, - 'search_key': searches['search'], - 'search_wishlist': searches['search_wishlist'], - 'search_tags': search_tags, - 'tag_categories': tag_categories, - # environment - 'is_html_empty': is_html_empty, - 'hostname': request.httprequest.host.split(':')[0], - 'user_event_manager': request.env.user.has_group('event.group_event_manager'), - } - - # ------------------------------------------------------------ - # PAGE VIEW - # ------------------------------------------------------------ - - @http.route('''/event/<model("event.event", "[('website_track', '=', True)]"):event>/track/<model("event.track", "[('event_id', '=', event.id)]"):track>''', - type='http', auth="public", website=True, sitemap=True) - def event_track_page(self, event, track, **options): - track = self._fetch_track(track.id, allow_is_accepted=False) - - return request.render( - "website_event_track_session.event_track_main", - self._event_track_page_get_values(event, track.sudo(), **options) - ) - - def event_track_view(self, event, track, **post): - return self.event_track_page(event, track, **post) - - def _event_track_page_get_values(self, event, track, **options): - track = track.sudo() - - option_widescreen = options.get('widescreen', False) - option_widescreen = bool(option_widescreen) if option_widescreen != '0' else False - # search for tracks list - tracks_other = track._get_track_suggestions( - restrict_domain=self._get_event_tracks_base_domain(track.event_id), - limit=10 - ) - - return { - # event information - 'event': event, - 'main_object': track, - 'track': track, - # sidebar - 'tracks_other': tracks_other, - # options - 'option_widescreen': option_widescreen, - # environment - 'is_html_empty': is_html_empty, - 'hostname': request.httprequest.host.split(':')[0], - 'user_event_manager': request.env.user.has_group('event.group_event_manager'), - } - - # ------------------------------------------------------------ - # TOOLS - # ------------------------------------------------------------ - - def _get_search_tags(self, tag_search): - # TDE FIXME: make me generic (slides, event, ...) - try: - tag_ids = literal_eval(tag_search) - except Exception: - tags = request.env['event.track.tag'].sudo() - else: - # perform a search to filter on existing / valid tags implicitly - tags = request.env['event.track.tag'].sudo().search([('id', 'in', tag_ids)]) - return tags - - def _get_dt_in_event_tz(self, datetimes, event): - tz_name = event.date_tz - return [ - utc.localize(dt, is_dst=False).astimezone(timezone(tz_name)) - for dt in datetimes - ] diff --git a/addons/website_event_track_session/data/event_track_demo.xml b/addons/website_event_track_session/data/event_track_demo.xml deleted file mode 100644 index c9fd08ccd84..00000000000 --- a/addons/website_event_track_session/data/event_track_demo.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo><data> - - <record id="website_event_track.event_7_track_1" model="event.track"> - <field name="website_cta" eval="True"/> - <field name="website_cta_title">Try Now</field> - <field name="website_cta_url">http://www.example.com</field> - <field name="website_cta_delay">10</field> - </record> - <record id="website_event_track.event_7_track_4" model="event.track"> - <field name="website_cta" eval="True"/> - <field name="website_cta_title">Try Now</field> - <field name="website_cta_url">http://www.example.com</field> - <field name="website_cta_delay">10</field> - </record> - -</data></odoo> diff --git a/addons/website_event_track_session/models/__init__.py b/addons/website_event_track_session/models/__init__.py deleted file mode 100644 index e3798014924..00000000000 --- a/addons/website_event_track_session/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import event_track diff --git a/addons/website_event_track_session/models/event_track.py b/addons/website_event_track_session/models/event_track.py deleted file mode 100644 index 7e012156e38..00000000000 --- a/addons/website_event_track_session/models/event_track.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from datetime import timedelta -from random import randint -from pytz import utc - -from odoo import api, fields, models -from odoo.osv import expression - - -class EventTrack(models.Model): - _inherit = "event.track" - - # Call to action - website_cta = fields.Boolean('Magic Button') - website_cta_title = fields.Char('Button Title') - website_cta_url = fields.Char('Button Target URL') - website_cta_delay = fields.Integer('Button appears') - # time information for track - is_track_live = fields.Boolean( - 'Is Track Live', compute='_compute_track_time_data', - help="Track has started and is ongoing") - is_track_soon = fields.Boolean( - 'Is Track Soon', compute='_compute_track_time_data', - help="Track begins soon") - is_track_today = fields.Boolean( - 'Is Track Today', compute='_compute_track_time_data', - help="Track begins today") - is_track_upcoming = fields.Boolean( - 'Is Track Upcoming', compute='_compute_track_time_data', - help="Track is not yet started") - is_track_done = fields.Boolean( - 'Is Track Done', compute='_compute_track_time_data', - help="Track is finished") - track_start_remaining = fields.Integer( - 'Minutes before track starts', compute='_compute_track_time_data', - help="Remaining time before track starts (seconds)") - track_start_relative = fields.Integer( - 'Minutes compare to track start', compute='_compute_track_time_data', - help="Relative time compared to track start (seconds)") - # time information for CTA - is_website_cta_live = fields.Boolean( - 'Is CTA Live', compute='_compute_cta_time_data', - help="CTA button is available") - website_cta_start_remaining = fields.Integer( - 'Minutes before CTA starts', compute='_compute_cta_time_data', - help="Remaining time before CTA starts (seconds)") - - @api.depends('date', 'date_end') - def _compute_track_time_data(self): - """ Compute start and remaining time for track itself. Do everything in - UTC as we compute only time deltas here. """ - now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0)) - for track in self: - if not track.date: - track.is_track_live = track.is_track_soon = track.is_track_today = track.is_track_upcoming = track.is_track_done = False - track.track_start_relative = track.track_start_remaining = 0 - continue - date_begin_utc = utc.localize(track.date, is_dst=False) - date_end_utc = utc.localize(track.date_end, is_dst=False) - track.is_track_live = date_begin_utc <= now_utc < date_end_utc - track.is_track_soon = (date_begin_utc - now_utc).total_seconds() < 30*60 if date_begin_utc > now_utc else False - track.is_track_today = date_begin_utc.date() == now_utc.date() - track.is_track_upcoming = date_begin_utc > now_utc - track.is_track_done = date_end_utc <= now_utc - if date_begin_utc >= now_utc: - track.track_start_relative = int((date_begin_utc - now_utc).total_seconds()) - track.track_start_remaining = track.track_start_relative - else: - track.track_start_relative = int((now_utc - date_begin_utc).total_seconds()) - track.track_start_remaining = 0 - - @api.depends('date', 'date_end', 'website_cta', 'website_cta_delay') - def _compute_cta_time_data(self): - """ Compute start and remaining time for track itself. Do everything in - UTC as we compute only time deltas here. """ - now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0)) - for track in self: - if not track.website_cta: - track.is_website_cta_live = track.website_cta_start_remaining = False - continue - - date_begin_utc = utc.localize(track.date, is_dst=False) + timedelta(minutes=track.website_cta_delay or 0) - date_end_utc = utc.localize(track.date_end, is_dst=False) - track.is_website_cta_live = date_begin_utc <= now_utc <= date_end_utc - if date_begin_utc >= now_utc: - td = date_begin_utc - now_utc - track.website_cta_start_remaining = int(td.total_seconds()) - else: - track.website_cta_start_remaining = 0 - - @api.model_create_multi - def create(self, values_list): - for values in values_list: - if values.get('website_cta_url'): - values['website_cta_url'] = self.env['res.partner']._clean_website(values['website_cta_url']) - return super(EventTrack, self).create(values_list) - - def write(self, values): - if values.get('website_cta_url'): - values['website_cta_url'] = self.env['res.partner']._clean_website(values['website_cta_url']) - return super(EventTrack, self).write(values) - - def _get_track_suggestions(self, restrict_domain=None, limit=None): - """ Returns the next tracks suggested after going to the current one - given by self. Tracks always belong to the same event. - - Heuristic is - - * live first; - * then ordered by start date, finished being sent to the end; - * wishlisted (manually or by default); - * tag matching with current track; - * location matching with current track; - * finally a random to have an "equivalent wave" randomly given; - - :param restrict_domain: an additional domain to restrict candidates; - :param limit: number of tracks to return; - """ - self.ensure_one() - - base_domain = [ - '&', - ('event_id', '=', self.event_id.id), - ('id', '!=', self.id), - ] - if restrict_domain: - base_domain = expression.AND([ - base_domain, - restrict_domain - ]) - - track_candidates = self.search(base_domain, limit=None, order='date asc') - if not track_candidates: - return track_candidates - - track_candidates = track_candidates.sorted( - lambda track: - (track.is_published, - track.is_track_live, - track.track_start_remaining > 0, - -1 * track.track_start_remaining, - track.is_reminder_on, - not track.wishlisted_by_default, - len(track.tag_ids & self.tag_ids), - track.location_id == self.location_id, - randint(0, 20), - ), reverse=True - ) - - return track_candidates[:limit] - - def get_backend_menu_id(self): - return self.env.ref('event.event_main_menu').id diff --git a/addons/website_event_track_session/tests/__init__.py b/addons/website_event_track_session/tests/__init__.py deleted file mode 100644 index c4e08033d49..00000000000 --- a/addons/website_event_track_session/tests/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import test_track_internals diff --git a/addons/website_event_track_session/views/assets.xml b/addons/website_event_track_session/views/assets.xml deleted file mode 100644 index fd9b752732e..00000000000 --- a/addons/website_event_track_session/views/assets.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo> - - <template id="assets_frontend" inherit_id="website.assets_frontend" name="Event Sessions Assets Frontend"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website_event_track_session/static/src/scss/event_track_templates.scss"/> - </xpath> - </template> - -</odoo> diff --git a/addons/website_event_track_session/views/event_track_templates_agenda.xml b/addons/website_event_track_session/views/event_track_templates_agenda.xml deleted file mode 100644 index 09ca68fa467..00000000000 --- a/addons/website_event_track_session/views/event_track_templates_agenda.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo> - -<template id="agenda_main_track" name="Track Agenda: Track (Session)" - inherit_id="website_event_track.agenda_main_track"> - <xpath expr="//div[hasclass('o_weagenda_track_badges')]/small[1]" position="before"> - <small t-if="track.is_track_live and not track.is_track_done and track.website_published" - class="mx-1 badge badge-danger">Live - </small> - </xpath> -</template> - -</odoo> diff --git a/addons/website_event_track_session/views/event_track_templates_list.xml b/addons/website_event_track_session/views/event_track_templates_list.xml deleted file mode 100644 index c841201cab7..00000000000 --- a/addons/website_event_track_session/views/event_track_templates_list.xml +++ /dev/null @@ -1,380 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo> - -<template id="tracks_session" - inherit_id="website_event_track.tracks"> - <!-- New main layout --> - <xpath expr="//div[@id='oe_structure_website_event_track_tracks_1']" position="before"> - <div class="o_wevent_online o_wesession_index"> - <!-- Options --> - <t t-set="option_track_wishlist" t-value="not event.is_done and request.website.viewref('website_event_track_session.session_topbar_wishlist').active"/> - <!-- Topbar --> - <t t-call="website_event_track_session.session_topbar"/> - <!-- Drag/Drop Area --> - <div id="oe_structure_wesession_index_1" class="oe_structure"/> - <!-- Content --> - <div class="o_wesession_container container"> - <div class="row"> - <t t-call="website_event_track_session.tracks_search"/> - </div> - <div class="row"> - <t t-call="website_event_track_session.tracks_main"/> - </div> - </div> - <!-- Drag/Drop Area --> - <div id="oe_structure_wesession_index_2" class="oe_structure mb-5"/> - </div> - </xpath> - <!-- Reset existing template as nothing to keep --> - <xpath expr="//div[@id='oe_structure_website_event_track_tracks_1']" position="replace"/> - <xpath expr="//section" position="replace"/> - <xpath expr="//div[@id='oe_structure_website_event_track_tracks_2']" position="replace"/> -</template> - -<!-- ============================================================ --> -<!-- TOPBAR: BASE NAVIGATION --> -<!-- ============================================================ --> - -<!-- Main topbar --> -<template id="session_topbar" name="Tracks Tools"> - <nav class="navbar navbar-light border-top shadow-sm d-print-none"> - <div class="container"> - <div class="d-flex flex-column flex-sm-row justify-content-between w-100"> - <ul class="o_wesession_topbar_filters o_wevent_index_topbar_filters nav"> - <!-- Optional wishlist filter --> - <li t-if="option_track_wishlist" class="nav-item dropdown mr-2 my-1"> - <a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown"> - <i class="fa fa-folder-open"/> Wishlist - </a> - <div class="dropdown-menu"> - <a t-att-href="'/event/%s/track?%s' % ( - slug(event), - keep_query('*', search_wishlist='') - )" - class="dropdown-item d-flex align-items-center justify-content-between"> - All Talks - </a> - <a t-att-href="'/event/%s/track?%s' % ( - slug(event), - keep_query('*', search_wishlist='1') - )" - t-attf-class="dropdown-item d-flex align-items-center justify-content-between #{'active' if search_wishlist else ''}"> - Wishlisted - </a> - </div> - </li> - </ul> - <div class="d-flex align-items-center flex-wrap pl-sm-3 pr-0"> - <t t-call="website_event.events_search_box"> - <t t-set="_searches" t-value="searches"/> - <t t-set="action" t-value="'/event/%s/track' % (slug(event))"/> - <t t-set="_placeholder" t-value="'Search a talk ...'"/> - </t> - </div> - </div> - </div> - </nav> -</template> - -<!-- Option: Topbar: optional tags filters --> -<template id="session_topbar_tag" - inherit_id="website_event_track_session.session_topbar" - name="Filter by Tags" - active="True" - customize_show="True"> - <xpath expr="//ul[hasclass('o_wesession_topbar_filters')]" position="inside"> - <t t-foreach="tag_categories" t-as="tag_category"> - <li t-if="tag_category.tag_ids and any(tag.color for tag in tag_category.tag_ids)" class="nav-item dropdown mr-2 my-1"> - <a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown"> - <i class="fa fa-folder-open"/> - <t t-esc="tag_category.name"/> - </a> - <div class="dropdown-menu"> - <t t-foreach="tag_category.tag_ids" t-as="tag"> - <a t-att-href="'/event/%s/track?%s' % ( - slug(event), - keep_query('*', tags=str((search_tags - tag).ids if tag in search_tags else (tag | search_tags).ids)) - )" - t-if="tag.color" - t-attf-class="dropdown-item d-flex align-items-center justify-content-between #{'active' if tag in search_tags else ''}"> - <t t-esc="tag.name"/> - </a> - </t> - </div> - </li> - </t> - </xpath> -</template> - -<!-- Option: Tracks display: optional wishlist --> -<template id="session_topbar_wishlist" - inherit_id="website_event_track_session.session_topbar" - name="Allow Wishlists" - active="True" - customize_show="True"> - <xpath expr="//ul[hasclass('o_wesession_topbar_filters')]" position="inside"> - </xpath> -</template> - -<!-- ============================================================ --> -<!-- CONTENT: MAIN TEMPLATES --> -<!-- ============================================================ --> - -<!-- Tracks Main Display --> -<template id="tracks_main" name="Tracks: Main Display"> - <!-- No tracks --> - <t t-if="not tracks"> - <div class="col-12"> - <div class="h2 mb-3">No track found.</div> - <div t-if="search_key" class="alert alert-info text-center"> - <p class="m-0">We did not find any track matching your <strong t-esc="search_key"/> search.</p> - </div> - <div t-else="" class="alert alert-info text-center" groups="event.group_event_manager"> - <p class="m-0">Schedule some tracks to get started !</p> - </div> - </div> - </t> - <!-- Cards --> - <div class="col-12" t-call="website_event_track_session.tracks_display_cards"/> - <!-- List --> - <div class="col-12" t-call="website_event_track_session.tracks_display_list"/> -</template> - -<!-- Tracks: Cards-based display --> -<template id="tracks_display_cards" name="Tracks: Cards Display"> - <div class="row mb-3" t-if="tracks_live"> - <div class="col-12"> - <h5 class="m-0 text-danger">Live Now</h5> - <hr class="mt-2 pb-1 mb-1"/> - </div> - <div t-foreach="tracks_live" t-as="track" class="col-md-6 col-lg-3 mb-4"> - <t t-call="website_event_track_session.tracks_cards_track"/> - </div> - </div> - <div class="row mb-3" t-if="tracks_soon"> - <div class="col-12"> - <h5 class="m-0 text-danger">Coming soon ...</h5> - <hr class="mt-2 pb-1 mb-1"/> - </div> - <div t-foreach="tracks_soon" t-as="track" class="col-md-6 col-lg-3 mb-4"> - <t t-call="website_event_track_session.tracks_cards_track"/> - </div> - </div> -</template> - -<!-- Tracks: List-based display --> -<template id="tracks_display_list" name="Tracks: List Display"> - <div t-if="tracks" class="o_wesession_list mb-3"> - <ul class="list-unstyled"> - <li t-foreach="tracks_by_day" t-as="tracks_info" - class="mb-5"> - <t t-set="tracks_date" t-value="tracks_info['date']"/> - <t t-set="tracks_header_name" t-value="tracks_info['name']"/> - <t t-set="tracks" t-value="tracks_info['tracks']"/> - <!-- DAY HEADER --> - <div class="o_we_track_day_header w-100"> - <div t-if="tracks_date" class="d-flex"> - <span class="h1 m-0 font-weight-bold" t-esc="tracks_date" - t-options="{'widget': 'date', 'format': 'EEEE dd'}"/> - <div class="d-flex flex-column ml-2"> - <span class="font-weight-bold" t-esc="tracks_date" - t-options="{'widget': 'date', 'format': 'MMMM'}"/> - <span class="font-weight-bold" t-esc="tracks_date" - t-options="{'widget': 'date', 'format': 'YYYY'}"/> - </div> - </div> - <div t-elif="tracks_header_name"> - <span class="h1 m-0 font-weight-bold" - t-esc="tracks_header_name"/> - </div> - <hr class="mt-2 pb-1 mb-1"/> - </div> - <!-- DAY TRACKS LIST --> - <div t-foreach="tracks" t-as="track" class="row mt8 o_wesession_list_item"> - <div class="col-md-7"> - <span class="h5 mb0"> - <a t-if="track.is_published or user_event_manager" - t-att-href="track.website_url"> - <span t-field="track.name"/> - </a> - <t t-else=""> - <span t-field="track.name"/> - </t> - <span t-if="not track.is_published and user_event_manager" - class="badge badge-danger ml-2 o_wevent_online_badge_unpublished"> - Unpublished - </span> - </span> - <div class="text-muted"> - <span class="text-muted" t-esc="track.partner_name"/> - <t t-if="track.partner_name"> &bull; </t> - <span t-esc="track.duration" - t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'hour', 'round': 'minute'}"/> - </div> - </div> - <div class="col-md-5"> - <div t-if="not event.is_done" class="float-right"> - <t t-if="tracks_date and today_tz <= tracks_date"> - <span t-if="track.is_track_live and not track.is_track_done" - class="badge badge-danger">Live</span> - <span t-elif="not track.is_track_done and track.is_track_soon"> - <span t-esc="track.track_start_remaining" - t-options="{'widget': 'duration', 'digital': False, 'format': 'narrow', - 'add_direction': True, 'unit': 'second', 'round': 'minute'}"/> - </span> - <t t-elif="not track.is_track_done and not track.is_track_soon"> - <span - class="mr-2" - t-esc="track.date" - t-options="{'widget': 'datetime', 'time_only': True, 'format': 'short'}"/> - <t t-if="option_track_wishlist" - t-call="website_event_track.track_widget_reminder"> - <t t-set="reminder_small" t-value="True"/> - </t> - </t> - <t t-else=""> - <span class="badge badge-info">Finished</span> - </t> - </t> - <t t-elif="not track.date and option_track_wishlist" - t-call="website_event_track_online.track_widget_reminder"> - <t t-set="reminder_small" t-value="True"/> - </t> - </div> - <t t-foreach="track.tag_ids" t-as="tag"> - <t t-if="tag.color" t-call="website_event_track_session.track_tag_badge_link"/> - </t> - </div> - </div> - </li> - </ul> - </div> -</template> - -<!-- ============================================================ --> -<!-- TOOL TEMPLATES --> -<!-- ============================================================ --> - -<template id="tracks_cards_track" name="Track Card"> - <a t-att-href="'/event/%s/track/%s' % (slug(track.event_id), slug(track))" class="text-decoration-none"> - <article t-att-class="'h-100 card border-0 shadow-sm o_wesession_track_card %s' % ('o_wesession_track_card_unpublished' if not track.is_published else '')" - itemscope="itemscope" itemtype="http://schema.org/Event"> - <div class="h-100 row no-gutters"> - <header class="overflow-hidden bg-secondary col-12 rounded-top"> - <small t-if="not track.is_published" class="o_wesession_track_card_header_badge bg-danger"> - <i class="fa fa-ban mr-2"/>Unpublished - </small> - - <div t-if="track.website_image_url" class="card-img-top" - t-attf-style="padding-top: 50%; background-image: url(#{track.website_image_url}); background-size: cover; background-position:center"> - <span t-if="option_track_wishlist and not track.is_track_live" class="position-absolute h3 mt-2 mr-2" style="right: 0; top: 0;"> - <t t-call="website_event_track.track_widget_reminder"> - <t t-set="reminder_light" t-value="True"/> - <t t-set="light_theme" t-value="True"/> - </t> - </span> - </div> - <div t-else="" class="o_wesession_gradient card-img-top position-relative" - style="padding-top: 50%;"> - <span t-if="option_track_wishlist" class="position-absolute h3 mt-2 mr-2" style="right: 0; top: 0;"> - <t t-call="website_event_track.track_widget_reminder"> - <t t-set="reminder_light" t-value="True"/> - </t> - </span> - <i class="fa fa-glass fa-2x mx-2 mb-3 position-absolute text-white-75" style="right:0; bottom: 0;"/> - </div> - </header> - <div class="col-12"> - <main class="card-body"> - <!-- Title --> - <h5 class="card-title mt-0 mb-0 text-truncate"> - <span t-field="track.name" itemprop="name"/> - </h5> - <!-- Tags> --> - <div> - <t t-foreach="track.tag_ids" t-as="tag"> - <t t-if="tag.color" t-call="website_event_track_session.track_tag_badge_info"/> - </t> - </div> - </main> - </div> - <!-- Footer --> - <footer class="small align-self-end w-100 card-footer"> - <div class="d-flex justify-content-between align-items-center"> - <!-- Speaker --> - <span class="text-muted text-truncate" t-field="track.partner_name" itemprop="performer"/> - <!-- Starts --> - <span class="text-muted ml-auto"> - <t t-if="track.is_track_upcoming > 0">In - <span class="text-muted ml-auto" t-field="track.track_start_remaining" itemprop="duration" - t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'second', 'round': 'minute'}"/> - </t> - <t t-else=""> - <span class="text-muted ml-auto" t-field="track.track_start_relative" itemprop="duration" - t-options="{'widget': 'duration', 'digital': False, 'format': 'short', 'unit': 'second', 'round': 'minute'}"/> - ago - </t> - </span> - </div> - </footer> - </div> - </article> - </a> -</template> - -<!-- Searched tags --> -<template id="tracks_search" name="Tracks: search tags"> - <div class="d-flex align-items-center mb-3"> - <span t-if="search_wishlist" - class="align-items-baseline border d-inline-flex pl-2 mt-3 rounded ml16 mb-2 bg-white"> - <i class="fa fa-bell mr-2 text-muted"/> Wishlisted Talks - <a t-att-href="'/event/%s/track?%s' % (slug(event), keep_query('*', search_wishlist=''))" - class="btn border-0 py-1"> - × - </a> - </span> - - <t t-foreach="search_tags" t-as="tag"> - <span class="align-items-baseline border d-inline-flex pl-2 mt-3 rounded ml16 mb-2 bg-white"> - <i class="fa fa-tag mr-2 text-muted"/> - <t t-esc="tag.display_name"/> - <a t-att-href="'/event/%s/track?%s' % (slug(event), keep_query('*', tags=str((search_tags - tag).ids)))" - class="btn border-0 py-1"> - × - </a> - </span> - </t> - </div> -</template> - -<!-- ============================================================ --> -<!-- MISC TOOLS --> -<!-- ============================================================ --> - -<template id="track_tag_badge_link" name="Track: Tag Badge Link"> - <a t-if="search_tags" - t-att-href="'/event/%s/track?%s'% ( - slug(event), - keep_query('*', tags=str((search_tags - tag).ids if tag in search_tags else (tag | search_tags).ids)) - )" - t-att-class="'badge %s' % ('badge-primary' if tag in search_tags else 'o_tag_color_hovered_0')" - t-esc="tag.name"/> - <a t-else="" - t-att-href="'/event/%s/track?%s'% ( - slug(event), - keep_query('*', tags=str(tag.ids)) - )" - t-att-class="'badge o_tag_color_hovered_%s' % (tag.color)" - t-esc="tag.name"/> -</template> - -<template id="track_tag_badge_info" name="Track: Tag Badge Info"> - <span t-if="search_tags" - t-att-class="'badge %s' % ('badge-primary' if tag in search_tags else 'o_tag_color_0')" - t-esc="tag.name"/> - <span t-else="" - t-att-class="'badge o_tag_color_%s' % (tag.color)" - t-esc="tag.name"/> -</template> - -</odoo> diff --git a/addons/website_event_track_session/views/event_track_templates_misc.xml b/addons/website_event_track_session/views/event_track_templates_misc.xml deleted file mode 100644 index 1f20d5868bf..00000000000 --- a/addons/website_event_track_session/views/event_track_templates_misc.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo><data> - - <!-- De-activate old customize --> - <record id="website_event_track.tracks_filter" model="ir.ui.view"> - <field name="active" eval="False"/> - <field name="customize_show" eval="False"/> - </record> - <record id="website_event_track.tracks_wishlist" model="ir.ui.view"> - <field name="active" eval="False"/> - <field name="customize_show" eval="False"/> - </record> - <record id="website_event_track.track_view_wishlist" model="ir.ui.view"> - <field name="active" eval="False"/> - <field name="customize_show" eval="False"/> - </record> - -</data></odoo> diff --git a/addons/website_event_track_session/views/event_track_templates_page.xml b/addons/website_event_track_session/views/event_track_templates_page.xml deleted file mode 100644 index bcc4078c647..00000000000 --- a/addons/website_event_track_session/views/event_track_templates_page.xml +++ /dev/null @@ -1,216 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<odoo> - -<template id="event_track_main" name="Event Exhibitor"> - <t t-call="website_event.layout"> - <div class="o_wevent_online o_wevent_online_bg o_wesession_index"> - <!-- Options --> - <t t-set="option_widescreen" t-value="option_widescreen or False"/> - <t t-set="option_track_wishlist" t-value="not event.is_done and request.website.viewref('website_event_track_session.session_topbar_wishlist').active"/> - <!-- Drag/Drop Area --> - <div id="oe_structure_wesession_track_index_1" class="oe_structure"/> - <!-- Content --> - <div t-att-class="'o_wevent_online_page_container %s' % ('container pb-3' if not option_widescreen else 'pb-3')"> - <div class="row mb-5 mx-0"> - <t t-call="website_event_track_session.event_track_aside"/> - <t t-call="website_event_track_session.event_track_content"/> - </div> - </div> - <!-- Drag/Drop Area --> - <div id="oe_structure_wesession_track_index_2" class="oe_structure"/> - </div> - </t> -</template> - -<!-- ============================================================ --> -<!-- CONTENT: MAIN TEMPLATES --> -<!-- ============================================================ --> - -<template id="event_track_content" name="Track: Main Description"> - <div name="o_wesession_track_main" - t-att-class="'col-12 o_wevent_online_page_main o_wesession_track_main bg-white p-0 %s' % ('col-md-9 col-lg-10' if option_widescreen else 'col-md-8 col-lg-9')"> - <!-- LIVE INFORMATIONS --> - <div t-if="not track.event_id.is_ongoing" class="pt-3"> - <div class="mx-3 alert alert-warning"> - Event <span t-esc="track.event_id.name" class="font-weight-bold"/> - <span t-if="track.event_id.start_today"> - starts in - <span t-esc="track.event_id.start_remaining" - t-options="{'widget': 'duration', 'digital': False, 'unit': 'minute', 'round': 'minute'}"/> - </span> - <span t-else=""> - starts at - <span t-field="track.event_id.with_context(tz=track.event_id.date_tz).date_begin" - t-options="{'format': 'long', 'tz_name': track.event_id.date_tz, 'hide_seconds': True}"/> - </span> - </div> - </div> - <div t-elif="track.track_start_remaining" class="pt-3"> - <div class="mx-3 alert alert-warning"> - Starting in - <span t-esc="track.track_start_remaining" - t-options="{'widget': 'duration', 'digital': False, 'unit': 'second', 'round': 'minute'}"/> - </div> - </div> - <!-- TRACK DESCRIPTION --> - <div class="o_wesession_track_main_description"> - <div class="mx-3 pt-3 mb-3 d-flex justify-content-between flex-column flex-md-row"> - <div class="d-flex flex-column"> - <span class="h4 mb-0" t-esc="track.name"/> - <div> - <t t-foreach="track.tag_ids" t-as="tag"> - <span t-if="tag.color" - t-att-class="'badge o_tag_color_hovered_%s' % (tag.color)" - t-esc="tag.name"/> - </t> - </div> - </div> - <div class="o_we_track_action_buttons d-flex justify-content-md-end align-items-center flex-wrap"> - <div class="o_we_track_reminder_button my-1"> - <div t-if="option_track_wishlist and not track.is_track_done" - t-call="website_event_track.track_widget_reminder"> - <t t-set="reminder_small" t-value="False"/> - <t t-set="reminder_light" t-value="False"/> - </div> - </div> - </div> - </div> - <div class="mx-3 text-muted"> - <t t-if="track.location_id"> - <strong>Location:</strong> <span t-field="track.location_id"/> - <span> - </span> - </t> - <t t-if="track.date"> - <span t-field="track.date" - t-options='{"hide_seconds":"True", "format": "short"}'/> - - - <span t-field="track.date_end" - t-options='{"hide_seconds":"True", "format": "short"}'/> - <t t-if="event.date_tz"> - (<span t-field="track.date_end" t-options='{"format": "zzz"}'/>) - </t> - </t> - <t t-if="track.duration"> - (<span t-field="track.duration" - t-options='{"widget": "duration", "unit": "hour", "round": "minute"}'/>) - </t> - </div> - - <hr class="mt-2 mb-0"/> - - <!-- ABOUT AUTHOR --> - <div class="mx-3"> - <div class="mt-2 d-flex"> - <span t-if="track.image" t-field="track.image" class="o_wevent_online_page_avatar" - t-options="{'widget': 'image', 'class': 'rounded-circle', 'max_width': '96'}"/> - <div class="pl-2 pr-0 pr-md-2 d-flex flex-column"> - <span t-field="track.partner_name" class="font-weight-bold mb-2"/> - <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_function"> - <i class="fa fa-briefcase mr-2"/><span t-esc="track.partner_function"/> - <t t-if="track.partner_company_name"> - <span>&nbsp;at&nbsp;</span><span t-esc="track.partner_company_name"/> - </t> - </span> - <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_id.website"> - <i class="fa fa-home mr-2"/><a t-att-href="track.partner_id.website"><span t-field="track.partner_id.website"/></a> - </span> - <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_email"> - <i class="fa fa-envelope mr-2"/><a t-att-mailto="track.partner_email"><span t-field="track.partner_email"/></a> - </span> - <span class="mb-1 d-flex align-items-baseline text-break" t-if="track.partner_phone"> - <i class="fa fa-phone mr-2"/><span t-field="track.partner_phone"/> - </span> - </div> - </div> - <div t-field="track.partner_biography" class="oe_no_empty"/> - <hr t-if="not is_html_empty(track.description)" class="mt-2 pb-1 mb-1"/> - </div> - <div t-field="track.description" class="my-2 mx-3 oe_no_empty"/> - </div> - </div> -</template> - -<!-- ============================================================ --> -<!-- ASIDE: CONTROL PANEL --> -<!-- ============================================================ --> - -<template id="event_track_aside" name="Track: Aside"> - <div t-att-class="'col-12 pl-0 pr-0 pr-md-3 o_wevent_online_page_aside o_wesession_track_aside %s' % ('col-md-3 col-lg-2' if option_widescreen else 'col-md-4 col-lg-3')"> - <div class="bg-white pt-0 pt-md-3 o_wevent_online_page_aside_content"> - <div class="mx-2" t-if="track.website_cta"> - <t t-set="cta_coundown" t-value="bool(track.website_cta_start_remaining)"/> - <div t-if="cta_coundown" class="text-center mt-2 mt-md-0 w-100 btn btn-primary d-none"> - <t t-call="website_event.display_timer_widget"> - <t t-set="pre_remaining_time" t-value="int(track.track_start_remaining)"/> - <!--<t t-set="pre_countdown_text" t-value="'Talk starts in'"/>--> - <t t-set="pre_countdown_display" t-value="bool(False)"/> - <t t-set="main_remaining_time" t-value="int(track.website_cta_start_remaining)"/> - <!--<t t-set="main_countdown_text" t-value="'Magic happens in'"/>--> - <t t-set="main_countdown_display" t-value="bool(False)"/> - <t t-set="display_class" t-value="'.o_event_cta_action'"/> - </t> - </div> - <div t-att-class="'o_event_cta_action %s' % ('d-none' if cta_coundown else '')"> - <a t-att-href="track.website_cta_url" - target="_blank" - class="btn btn-primary w-100 mb-3 mt-2 mt-md-0"> - <span t-esc="track.website_cta_title"/> - </a> - </div> - </div> - <div class="d-flex align-items-center justify-content-between mx-2"> - <ul class="nav nav-tabs o_wesession_track_aside_nav d-flex border-0" role="tablist"> - <li class="nav-item flex-grow-1"> - <a href="#track_list" aria-controls="track_list" class="nav-link active" role="tab" data-toggle="tab"> - Talks - </a> - </li> - </ul> - <a href="#collapse_track_aside" data-toggle="collapse" class="d-md-none p-2 text-decoration-none o_wevent_online_page_aside_collapse collapsed"> - <i class="fa fa-chevron-down d-md-none"/> - </a> - </div> - <div id="collapse_track_aside" - class="tab-content collapse d-md-block o_wesession_track_aside_tabs"> - <div class="tab-pane fade show active" id="track_list" role="tabpanel"> - <ul class="list-unstyled mb-0"> - <li t-foreach="tracks_other" t-as="track_other" class="w-100"> - <a t-if="user_event_manager or track_other.is_published" - class="d-block w-100 h-100 px-2 pt-2 pb-1 text-decoration-none" - t-att-href="track_other.website_url"> - <t t-call="website_event_track_session.event_track_aside_other_track"/> - </a> - <div t-else="" class="text-muted px-2 pt-2 pb-1"> - <t t-call="website_event_track_session.event_track_aside_other_track"/> - </div> - </li> - </ul> - </div> - </div> - </div> - </div> -</template> - -<template id="event_track_aside_other_track"> - <span t-esc="track_other.name" class="w-100"/> - <div class="d-flex align-items-center"> - <small class="text-muted" t-esc="track_other.partner_name"/> - <div class="d-inline-block ml-auto o_wesession_track_aside_info text-truncate"> - <small t-if="track_other.is_track_live and not track_other.is_track_done" - class="badge badge-danger">Live</small> - <small t-elif="track_other.is_track_done" - class="badge badge-light">Done</small> - <small t-elif="track_other.is_track_today and track_other.track_start_remaining" - class="badge badge-light"> - <span t-esc="track_other.track_start_remaining" - t-options="{'widget': 'duration', 'digital': False, 'add_direction': True, - 'unit': 'second', 'round': 'minute', 'format': 'narrow'}"/> - </small> - <div t-elif="track_other.date" class="badge badge-light"> - <span t-esc="track_other.date" t-options="{'widget': 'datetime', 'tz_name': track_other.event_id.date_tz, 'format': 'MMM. dd'}"/> - </div> - </div> - </div> -</template> - -</odoo> diff --git a/addons/website_event_track_session/views/event_track_views.xml b/addons/website_event_track_session/views/event_track_views.xml deleted file mode 100644 index a80870faf2d..00000000000 --- a/addons/website_event_track_session/views/event_track_views.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<odoo> - - <record id="event_track_view_form" model="ir.ui.view"> - <field name="name">event.track.view.form.inherit.session</field> - <field name="model">event.track</field> - <field name="inherit_id" ref="website_event_track.view_event_track_form"/> - <field name="arch" type="xml"> - <xpath expr="//page[@name='description']" position="after"> - <page string="Interactivity" name="interactivity"> - <group> - <group name="event_track_cta_group"> - <field name="website_cta"/> - <field name="website_cta_title" placeholder="e.g. Get Yours Now !" - attrs="{'invisible': [('website_cta', '=', False)], - 'required': [('website_cta', '=', True)]}"/> - <field name="website_cta_url" placeholder="e.g. http://www.example.com" - attrs="{'invisible': [('website_cta', '=', False)], - 'required': [('website_cta', '=', True)]}"/> - <label for="website_cta_delay" - attrs="{'invisible': [('website_cta', '=', False)]}"/> - <div attrs="{'invisible': [('website_cta', '=', False)]}"> - <field name="website_cta_delay" class="oe_inline" - attrs="{'required': [('website_cta', '=', True)]}"/> minutes after talk start - </div> - </group> - </group> - </page> - </xpath> - </field> - </record> - -</odoo> |
