summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqmo-odoo <qmo@odoo.com>2020-01-17 10:22:08 +0000
committerThibault Delavallée <tde@odoo.com>2020-02-18 09:24:26 +0000
commitb8e33b24391dff076c21b53d85abb4f2c9692828 (patch)
treeb21e9a99cd79e7033b9955267af226b36586e00c
parentf652912398c2ff1ca174f47f30f7bef73605caec (diff)
[IMP] website_event: improve front-end display
This commit makes a few design improvements in the Event list in front-end after some feedback about its usability - Make the 'configure your registration' alter not editable (for studio) - Display the "is online" through a "tag" design, not just text - Remove remaining seats count - Some display cleaning and improvements (design) - Put the event date just below event title on event frontend list - apply some minor design improvements in the /register page. - Filter by month instead of weeks : This commit changes the date filtering in website_event. Before this commit, users could filter events by weeks. After this commit, users will be able to filter by months and will be able to filter events up to two months in the future. LINKS TaskID 2162438 Community PR odoo/odoo#44476 Co-Authored-By: David Beguin <dbe@odoo.com> Co-Authored-By: Quentin Mourier <qmo@odoo.com>
-rw-r--r--addons/website_event/controllers/main.py38
-rw-r--r--addons/website_event/views/event_templates.xml75
2 files changed, 55 insertions, 58 deletions
diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py
index dfb66f7f834..5733639002f 100644
--- a/addons/website_event/controllers/main.py
+++ b/addons/website_event/controllers/main.py
@@ -12,7 +12,7 @@ from odoo import fields, http, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website.controllers.main import QueryURL
from odoo.http import request
-from odoo.tools.misc import get_lang
+from odoo.tools.misc import get_lang, format_date
class WebsiteEventController(http.Controller):
@@ -32,37 +32,35 @@ class WebsiteEventController(http.Controller):
searches.setdefault('country', 'all')
website = request.website
+ today = datetime.today()
def sdn(date):
return fields.Datetime.to_string(date.replace(hour=23, minute=59, second=59))
def sd(date):
return fields.Datetime.to_string(date)
- today = datetime.today()
+
+ def get_month_filter_domain(filter_name, months_delta):
+ first_day_of_the_month = today.replace(day=1)
+ filter_string = _('This month') if months_delta == 0 \
+ else format_date(request.env, value=today + relativedelta(months=months_delta),
+ date_format='LLLL', lang_code=get_lang(request.env).code).capitalize()
+ return [filter_name, filter_string, [
+ ("date_end", ">=", sd(first_day_of_the_month + relativedelta(months=months_delta))),
+ ("date_begin", "<", sd(first_day_of_the_month + relativedelta(months=months_delta+1)))],
+ 0]
+
dates = [
- ['all', _('Next Events'), [("date_end", ">", sd(today))], 0],
+ ['all', _('Upcoming Events'), [("date_end", ">", sd(today))], 0],
['today', _('Today'), [
("date_end", ">", sd(today)),
("date_begin", "<", sdn(today))],
0],
- ['week', _('This Week'), [
- ("date_end", ">=", sd(today + relativedelta(days=-today.weekday()))),
- ("date_begin", "<", sdn(today + relativedelta(days=6-today.weekday())))],
- 0],
- ['nextweek', _('Next Week'), [
- ("date_end", ">=", sd(today + relativedelta(days=7-today.weekday()))),
- ("date_begin", "<", sdn(today + relativedelta(days=13-today.weekday())))],
- 0],
- ['month', _('This month'), [
- ("date_end", ">=", sd(today.replace(day=1))),
- ("date_begin", "<", (today.replace(day=1) + relativedelta(months=1)).strftime('%Y-%m-%d 00:00:00'))],
- 0],
- ['nextmonth', _('Next month'), [
- ("date_end", ">=", sd(today.replace(day=1) + relativedelta(months=1))),
- ("date_begin", "<", (today.replace(day=1) + relativedelta(months=2)).strftime('%Y-%m-%d 00:00:00'))],
- 0],
+ get_month_filter_domain('month', 0),
+ get_month_filter_domain('nextmonth1', 1),
+ get_month_filter_domain('nextmonth2', 2),
['old', _('Past Events'), [
- ("date_end", "<", today.strftime('%Y-%m-%d 00:00:00'))],
+ ("date_end", "<", sd(today))],
0],
]
diff --git a/addons/website_event/views/event_templates.xml b/addons/website_event/views/event_templates.xml
index 9f705c987e8..3bd32369a92 100644
--- a/addons/website_event/views/event_templates.xml
+++ b/addons/website_event/views/event_templates.xml
@@ -59,7 +59,7 @@
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-calendar"/>
<t t-if="current_date" t-esc="current_date"/>
- <t t-else="">Next Events</t>
+ <t t-else="">Upcoming Events</t>
</a>
<div class="dropdown-menu">
<t t-foreach="dates" t-as="date">
@@ -160,8 +160,8 @@
</t>
<!-- List -->
<div t-foreach="event_ids" t-as="event" t-attf-class=" #{opt_event_size} mb-4">
- <article t-attf-class="#{opt_events_list_cards and 'card border-0 shadow-sm'}" itemscope="itemscope" itemtype="http://schema.org/Event">
- <div class="row no-gutters">
+ <article t-attf-class="h-100 #{opt_events_list_cards and 'card border-0 shadow-sm'}" itemscope="itemscope" itemtype="http://schema.org/Event">
+ <div class="h-100 row no-gutters">
<!-- Header -->
<header t-attf-class="overflow-hidden bg-secondary #{opt_events_list_columns and 'col-12 rounded-top' or 'col-sm-4 col-lg-3 rounded-left'} #{(not opt_events_list_cards) and 'rounded shadow'} #{(not opt_events_list_cards and not opt_events_list_columns) and 'rounded-top'}">
<!-- Image + Link -->
@@ -190,39 +190,34 @@
<main t-attf-class="#{opt_events_list_cards and 'card-body' or (opt_events_list_columns and 'py-3' or 'px-4')}">
<!-- Title -->
<h5 t-attf-class="card-title mt-2 mb-0 text-truncate #{(not event.website_published) and 'text-danger'}">
- <a t-attf-href="/event/#{ slug(event) }/#{(not event.menu_id) and 'register'}" class="text-reset text-decoration-none" itemprop="url">
+ <a t-attf-href="/event/#{ slug(event) }/#{(not event.menu_id) and 'register'}"
+ class="text-reset text-decoration-none"
+ itemprop="url">
<span t-field="event.name" itemprop="name"/>
</a>
+ <div class="badge badge-pill badge-info ml-2 mt-2 pt4 pb4" t-if="event.is_online">Online</div>
</h5>
- <!-- Organizer -->
- <div t-if="event.organizer_id" class="mb-3">
- <small class="text-muted text-truncate">Organizer: <span t-field="event.organizer_id" itemprop="organizer"/></small>
- </div>
- <!-- Location -->
- <div t-if="event.is_online">Online</div>
- <div t-else="" itemprop="location" t-field="event.address_id" t-options="{'widget': 'contact', 'fields': ['city'], 'no_marker': 'true'}"/>
<!-- Start Date & Time -->
<time itemprop="startDate" t-att-datetime="event.date_begin">
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'long'}"/> -
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'time_only': 'true', 'format': 'short'}"/>
</time>
+ <!-- Organizer -->
+ <div t-if="event.organizer_id" class="mb-3">
+ <small class="text-muted text-truncate">Organizer: <span t-field="event.organizer_id" itemprop="organizer"/></small>
+ </div>
+ <!-- Location -->
+ <div t-if="not event.is_online" itemprop="location" t-field="event.address_id" t-options="{'widget': 'contact', 'fields': ['city'], 'no_marker': 'true'}"/>
</main>
- <!-- Footer -->
- <footer t-attf-class="small #{opt_events_list_cards and 'card-footer' or ((not opt_events_list_columns) and 'border-top mx-4 mt-auto pt-2' or 'border-top py-2')}">
- <t t-if="event.event_registrations_open">
- <span class="text-danger"
- t-if="event.seats_availability == 'limited' and not event.seats_available">
- Sold Out
- </span>
- <span class="text-muted"
- t-if="event.seats_availability == 'limited' and
- event.seats_available and
- (event.seats_available &lt;5 or event.seats_available &lt;= ((event.seats_max or 0) / 4))">
- <em>Only <t t-esc="event.seats_available"/> Remaining</em>
- </span>
- </t>
- </footer>
</div>
+ <!-- Footer -->
+ <footer t-if="event.event_registrations_open"
+ t-attf-class="small align-self-end w-100 #{opt_events_list_cards and 'card-footer' or ((not opt_events_list_columns) and 'border-top mx-4 mt-auto pt-2' or 'border-top py-2')}">
+ <span class="text-danger"
+ t-if="event.seats_availability == 'limited' and not event.seats_available">
+ Sold Out
+ </span>
+ </footer>
</div>
</article>
</div>
@@ -403,7 +398,7 @@
<h2 t-field="event.subtitle" class="o_wevent_event_subtitle" placeholder="Event Subtitle"/>
</div>
</div>
- <div class="container mb-5">
+ <div class="container">
<t t-call="website_event.registration_template"/>
</div>
</t>
@@ -415,19 +410,21 @@
<!-- Event - Description -->
<template id="event_description_full" name="Event Description" track="1">
<t t-call="website_event.event_details">
- <section class="bg-200">
- <div class="container">
- <div class="row no-gutters mt-n5 pb-5">
+ <section class="bg-200 mt-n5">
+ <div class="container overflow-hidden">
+ <div class="row no-gutters mt-n4">
<!-- Description -->
- <div id="o_wevent_event_main_col" class="col-lg-8 bg-white rounded-left p-5 shadow-sm">
+ <div id="o_wevent_event_main_col" class="col-lg-8 bg-white px-5 pt-4 pb-0 shadow-sm">
<span t-field="event.description" itemprop="description"/>
</div>
- <div class="col-lg-4 bg-light rounded-right shadow-sm d-print-none">
+ <div class="col-lg-4 bg-light shadow-sm d-print-none">
<!-- Date & Time -->
<div class="o_wevent_sidebar_block">
<h6 class="o_wevent_sidebar_title">Date &amp; Time</h6>
- <span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'EEEE'}"/>
- <h4 class="my-1" t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'long'}" itemprop="startDate" t-att-datetime="event.date_begin"/>
+ <div class="d-flex">
+ <h5 t-field="event.with_context(tz=event.date_tz).date_begin" class="my-1 mr-1" t-options="{'date_only': 'true', 'format': 'EEEE'}"/>
+ <h5 class="my-1" t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'long'}" itemprop="startDate" t-att-datetime="event.date_begin"/>
+ </div>
<t t-if="not event.is_one_day">Start -</t>
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'time_only': 'true', 'format': 'short'}"/>
<t t-if="event.is_one_day">
@@ -436,8 +433,10 @@
</t>
<t t-else="">
<i class="fa fa-long-arrow-down d-block text-muted mx-3 my-2" style="font-size: 1.5rem"/>
- <span t-field="event.with_context(tz=event.date_tz).date_end" t-options="{'date_only': 'true', 'format': 'EEEE'}"/>
- <h4 class="my-1" t-field="event.with_context(tz=event.date_tz).date_end" t-options="{'date_only': 'true', 'format': 'long'}"/>
+ <div class="d-flex">
+ <h5 t-field="event.with_context(tz=event.date_tz).date_end" class="my-1 mr-1" t-options="{'date_only': 'true', 'format': 'EEEE'}"/>
+ <h5 class="my-1" t-field="event.with_context(tz=event.date_tz).date_end" t-options="{'date_only': 'true', 'format': 'long'}"/>
+ </div>
<t t-if="not event.is_one_day">End -</t>
<span t-field="event.with_context(tz=event.date_tz).date_end" t-options="{'time_only': 'true', 'format': 'short'}"/>
</t>
@@ -523,7 +522,7 @@
t-attf-action="/event/#{slug(event)}/registration/new" method="post"
class="mb-5" itemscope="itemscope" itemprop="offers" itemtype="http://schema.org/AggregateOffer">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
- <div id="o_wevent_tickets" class="bg-white rounded shadow-sm">
+ <div id="o_wevent_tickets" class="bg-white shadow-sm">
<t t-set="tickets" t-value="event.event_ticket_ids.filtered(lambda ticket: not ticket.is_expired)"/>
<!-- If some tickets expired and there is only one type left, we keep the same layout -->
@@ -619,7 +618,7 @@
</div>
</div>
</form>
- <div t-elif="request.env.user.has_group('event.group_event_manager')" class="alert alert-info mb-5 o_website_event_configuration" role="status">
+ <div t-elif="request.env.user.has_group('event.group_event_manager')" class="alert alert-info rounded-0 mb-5 o_website_event_configuration o_not_editable" role="status">
<a t-attf-href="/web#id=#{event.id}&amp;view_type=form&amp;model=event.event">
<i class="fa fa-pencil mr-2" role="img" aria-label="Create" title="Create"/><em>Configure Event Registration</em>
</a>