diff --git a/addons/event/models/event_event.py b/addons/event/models/event_event.py index 1ad89563585..0a6a7f79dc6 100644 --- a/addons/event/models/event_event.py +++ b/addons/event/models/event_event.py @@ -24,6 +24,29 @@ class EventType(models.Model): _description = 'Event Template' _order = 'sequence, id' + def _default_event_mail_type_ids(self): + return [(0, 0, + {'notification_type': 'mail', + 'interval_nbr': 0, + 'interval_unit': 'now', + 'interval_type': 'after_sub', + 'template_ref': 'mail.template, %i' % self.env.ref('event.event_subscription').id, + }), + (0, 0, + {'notification_type': 'mail', + 'interval_nbr': 1, + 'interval_unit': 'hours', + 'interval_type': 'before_event', + 'template_ref': 'mail.template, %i' % self.env.ref('event.event_reminder').id, + }), + (0, 0, + {'notification_type': 'mail', + 'interval_nbr': 3, + 'interval_unit': 'days', + 'interval_type': 'before_event', + 'template_ref': 'mail.template, %i' % self.env.ref('event.event_reminder').id, + })] + name = fields.Char('Event Template', required=True, translate=True) note = fields.Html(string='Note') sequence = fields.Integer() @@ -43,7 +66,9 @@ class EventType(models.Model): default_timezone = fields.Selection( _tz_get, string='Timezone', default=lambda self: self.env.user.tz or 'UTC') # communication - event_type_mail_ids = fields.One2many('event.type.mail', 'event_type_id', string='Mail Schedule') + event_type_mail_ids = fields.One2many( + 'event.type.mail', 'event_type_id', string='Mail Schedule', + default=_default_event_mail_type_ids) # ticket reports ticket_instructions = fields.Html('Ticket Instructions', translate=True, help="This information will be printed on your tickets.") @@ -69,6 +94,9 @@ class EventEvent(models.Model): def _default_description(self): return self.env['ir.ui.view']._render_template('event.event_default_descripton') + def _default_event_mail_ids(self): + return self.env['event.type']._default_event_mail_type_ids() + name = fields.Char(string='Event', translate=True, required=True) note = fields.Html(string='Note', store=True, compute="_compute_note", readonly=False) description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False, sanitize_form=False, default=_default_description) @@ -371,7 +399,7 @@ class EventEvent(models.Model): """ for event in self: if not event.event_type_id and not event.event_mail_ids: - event.event_mail_ids = False + event.event_mail_ids = self._default_event_mail_ids() continue # lines to keep: those with already sent emails or registrations diff --git a/addons/event/models/event_registration.py b/addons/event/models/event_registration.py index 27da716a968..74c320b6dde 100644 --- a/addons/event/models/event_registration.py +++ b/addons/event/models/event_registration.py @@ -235,7 +235,7 @@ class EventRegistration(models.Model): default_model='event.registration', default_res_id=self.id, default_use_template=bool(template), - default_template_ref='mail.template,%i' % template.id, + default_template_id=template.id, default_composition_mode='comment', custom_layout="mail.mail_notification_light", ) diff --git a/addons/event/models/event_tag.py b/addons/event/models/event_tag.py index dd097c333a7..0244f299861 100644 --- a/addons/event/models/event_tag.py +++ b/addons/event/models/event_tag.py @@ -29,6 +29,3 @@ class EventTag(models.Model): color = fields.Integer( string='Color Index', default=lambda self: self._default_color(), help='Tag color. No color means no display in kanban or front-end, to distinguish internal tags from public categorization tags.') - - def name_get(self): - return [(tag.id, "%s: %s" % (tag.category_id.name, tag.name)) for tag in self] diff --git a/addons/event/tests/test_event_internals.py b/addons/event/tests/test_event_internals.py index 17dd347a97b..9fb11beff6d 100644 --- a/addons/event/tests/test_event_internals.py +++ b/addons/event/tests/test_event_internals.py @@ -86,6 +86,7 @@ class TestEventData(TestEventCommon): 'name': 'Event Update Type', 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), + 'event_mail_ids': False, }) self.assertEqual(event.date_tz, self.env.user.tz) self.assertFalse(event.seats_limited) @@ -148,13 +149,12 @@ class TestEventData(TestEventCommon): # setup test records event_type_default = self.env['event.type'].create({ 'name': 'Type Default', - 'auto_confirm': True + 'auto_confirm': True, + 'event_type_mail_ids': False, }) event_type_mails = self.env['event.type'].create({ 'name': 'Type Mails', - 'auto_confirm': False - }) - event_type_mails.write({ + 'auto_confirm': False, 'event_type_mail_ids': [ Command.clear(), Command.create({ @@ -164,7 +164,7 @@ class TestEventData(TestEventCommon): 'interval_type': 'after_event', 'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder'), }) - ] + ], }) event = self.env['event.event'].create({ 'name': 'Event', @@ -307,6 +307,36 @@ class TestEventData(TestEventCommon): set(['Registration Ticket']) ) + @users('user_eventmanager') + def test_event_mail_default_config(self): + event = self.env['event.event'].create({ + 'name': 'Event Update Type', + 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), + 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), + }) + self.assertEqual(event.date_tz, self.env.user.tz) + self.assertFalse(event.seats_limited) + self.assertFalse(event.auto_confirm) + + #Event Communications: when no event type, default configuration + self.assertEqual(len(event.event_mail_ids), 3) + self.assertEqual(event.event_mail_ids[0].interval_unit, 'now') + self.assertEqual(event.event_mail_ids[0].interval_type, 'after_sub') + self.assertEqual(event.event_mail_ids[0].template_ref, self.env.ref('event.event_subscription')) + self.assertEqual(event.event_mail_ids[1].interval_nbr, 1) + self.assertEqual(event.event_mail_ids[1].interval_unit, 'hours') + self.assertEqual(event.event_mail_ids[1].interval_type, 'before_event') + self.assertEqual(event.event_mail_ids[1].template_ref, self.env.ref('event.event_reminder')) + self.assertEqual(event.event_mail_ids[2].interval_nbr, 3) + self.assertEqual(event.event_mail_ids[2].interval_unit, 'days') + self.assertEqual(event.event_mail_ids[2].interval_type, 'before_event') + self.assertEqual(event.event_mail_ids[2].template_ref, self.env.ref('event.event_reminder')) + + event.write({ + 'event_mail_ids': False + }) + self.assertEqual(event.event_mail_ids, self.env['event.mail']) + def test_event_mail_filter_template_on_event(self): """Test that the mail template are filtered to show only those which are related to the event registration model. diff --git a/addons/event_sms/tests/test_sms_schedule.py b/addons/event_sms/tests/test_sms_schedule.py index b9ecbeeb6c2..d9ac4cd7a15 100644 --- a/addons/event_sms/tests/test_sms_schedule.py +++ b/addons/event_sms/tests/test_sms_schedule.py @@ -29,6 +29,7 @@ class TestSMSSchedule(TestEventCommon, SMSCase): cls.event_0.write({ 'event_mail_ids': [ + (5, 0), (0, 0, { # right at subscription 'interval_unit': 'now', 'interval_type': 'after_sub', diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index c35ba3a44c3..573a5a5e3aa 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -1,21 +1,21 @@ # -*- coding: utf-8 -*- -import collections import babel.dates +import pytz import re import werkzeug -from werkzeug.datastructures import OrderedMultiDict -from werkzeug.exceptions import NotFound from ast import literal_eval from collections import defaultdict from datetime import datetime, timedelta +from dateutil.parser import parse from dateutil.relativedelta import relativedelta +from werkzeug.datastructures import OrderedMultiDict +from werkzeug.exceptions import NotFound 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.addons.event.controllers.main import EventController from odoo.http import request from odoo.osv import expression from odoo.tools.misc import get_lang, format_date @@ -27,6 +27,10 @@ class WebsiteEventController(http.Controller): if not qs or qs.lower() in '/events': yield {'loc': '/events'} + # ------------------------------------------------------------ + # EVENT LIST + # ------------------------------------------------------------ + @http.route(['/event', '/event/page/', '/events', '/events/page/'], type='http', auth="public", website=True, sitemap=sitemap_event) def events(self, page=1, **searches): Event = request.env['event.event'] @@ -152,7 +156,7 @@ class WebsiteEventController(http.Controller): 'current_type': current_type, 'event_ids': events, # event_ids used in website_event_track so we keep name as it is 'dates': dates, - 'categories': request.env['event.tag.category'].search([]), + 'categories': request.env['event.tag.category'].search([('is_published', '=', True)]), 'countries': countries, 'pager': pager, 'searches': searches, @@ -167,6 +171,10 @@ class WebsiteEventController(http.Controller): return request.render("website_event.index", values) + # ------------------------------------------------------------ + # EVENT PAGE + # ------------------------------------------------------------ + @http.route(['''/event//page/'''], type='http', auth="public", website=True, sitemap=False) def event_page(self, event, page, **post): values = { @@ -214,51 +222,6 @@ class WebsiteEventController(http.Controller): 'iCal_url': urls.get('iCal_url'), } - @http.route('/event/add_event', type='json', auth="user", methods=['POST'], website=True) - def add_event(self, event_name="New Event", **kwargs): - event = self._add_event(event_name, request.context) - return "/event/%s/register?enable_editor=1" % slug(event) - - def _add_event(self, event_name=None, context=None, **kwargs): - if not event_name: - event_name = _("New Event") - date_begin = datetime.today() + timedelta(days=(14)) - vals = { - 'name': event_name, - 'date_begin': fields.Date.to_string(date_begin), - 'date_end': fields.Date.to_string((date_begin + timedelta(days=(1)))), - 'seats_available': 1000, - 'website_id': request.website.id, - } - return request.env['event.event'].with_context(context or {}).create(vals) - - def get_formated_date(self, event): - start_date = fields.Datetime.from_string(event.date_begin).date() - end_date = fields.Datetime.from_string(event.date_end).date() - month = babel.dates.get_month_names('abbreviated', locale=get_lang(event.env).code)[start_date.month] - return ('%s %s%s') % (month, start_date.strftime("%e"), (end_date != start_date and ("-" + end_date.strftime("%e")) or "")) - - @http.route('/event/get_country_event_list', type='json', auth='public', website=True) - def get_country_events(self, **post): - Event = request.env['event.event'] - country_code = request.session['geoip'].get('country_code') - result = {'events': [], 'country': False} - events = None - domain = request.website.website_domain() - if country_code: - country = request.env['res.country'].search([('code', '=', country_code)], limit=1) - events = Event.search(domain + ['|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") - if not events: - events = Event.search(domain + [('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") - for event in events: - if country_code and event.country_id.code == country_code: - result['country'] = country - result['events'].append({ - "date": self.get_formated_date(event), - "event": event, - "url": event.website_url}) - return request.env['ir.ui.view']._render_template("website_event.country_events_list", result) - def _process_tickets_form(self, event, form_details): """ Process posted data about ticket order. Generic ticket are supported for event without tickets (generic registration). @@ -414,6 +377,75 @@ class WebsiteEventController(http.Controller): 'iCal_url': urls.get('iCal_url') } + # ------------------------------------------------------------ + # EDITOR (NEW EVENT) + # ------------------------------------------------------------ + + @http.route('/event/add_event', type='json', auth="user", methods=['POST'], website=True) + def add_event(self, name, event_start, event_end, address_values, **kwargs): + values = self._prepare_event_values(name, event_start, event_end, address_values) + event = request.env['event.event'].create(values) + return "/event/%s/register?enable_editor=1" % slug(event) + + def _prepare_event_values(self, name, event_start, event_end, address_values=None): + """ + Return the values to create a new event. + event_start,event_date are datetimes in the user tz. + address_values is used to either choose an existing location or create one as we allow it in the frontend. + """ + date_begin = parse(event_start).astimezone(pytz.utc).replace(tzinfo=None) + date_end = parse(event_end).astimezone(pytz.utc).replace(tzinfo=None) + address_id = request.env['res.partner'] + if address_values: + (address_pid, address_vals) = int(address_values[0]), address_values[1] + address_id = address_pid + if address_pid == 0: + address_id = request.env['res.partner'].create(address_vals).id + return { + 'name': name, + 'date_begin': date_begin, + 'date_end': date_end, + 'address_id': address_id, + 'seats_available': 1000, + 'website_id': request.website.id, + 'event_ticket_ids': request.env['event.event.ticket'], + } + + # ------------------------------------------------------------ + # TOOLS (JSON) + # ------------------------------------------------------------ + + @http.route('/event/get_country_event_list', type='json', auth='public', website=True) + def get_country_events(self, **post): + Event = request.env['event.event'] + country_code = request.session['geoip'].get('country_code') + result = {'events': [], 'country': False} + events = None + domain = request.website.website_domain() + if country_code: + country = request.env['res.country'].search([('code', '=', country_code)], limit=1) + events = Event.search(domain + ['|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") + if not events: + events = Event.search(domain + [('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") + for event in events: + if country_code and event.country_id.code == country_code: + result['country'] = country + result['events'].append({ + "date": self.get_formated_date(event), + "event": event, + "url": event.website_url}) + return request.env['ir.ui.view']._render_template("website_event.country_events_list", result) + + # ------------------------------------------------------------ + # TOOLS (HELPERS) + # ------------------------------------------------------------ + + def get_formated_date(self, event): + start_date = fields.Datetime.from_string(event.date_begin).date() + end_date = fields.Datetime.from_string(event.date_end).date() + month = babel.dates.get_month_names('abbreviated', locale=get_lang(event.env).code)[start_date.month] + return ('%s %s%s') % (month, start_date.strftime("%e"), (end_date != start_date and ("-" + end_date.strftime("%e")) or "")) + def _extract_searched_event_tags(self, searches): tags = request.env['event.tag'] if searches.get('tags'): diff --git a/addons/website_event/models/event_event.py b/addons/website_event/models/event_event.py index 9b138de5cb2..2874f72061c 100644 --- a/addons/website_event/models/event_event.py +++ b/addons/website_event/models/event_event.py @@ -24,7 +24,11 @@ class Event(models.Model): def _default_cover_properties(self): res = super()._default_cover_properties() - res['opacity'] = '0.4' + res.update({ + 'background-image': "url('/website_event/static/src/img/event_cover_4.jpg')", + 'opacity': '0.4', + 'resize_class': 'cover_auto' + }) return res # description diff --git a/addons/website_event/static/src/js/website_event.editor.js b/addons/website_event/static/src/js/website_event.editor.js index 48f3a995d08..4516e6ba43b 100644 --- a/addons/website_event/static/src/js/website_event.editor.js +++ b/addons/website_event/static/src/js/website_event.editor.js @@ -2,11 +2,257 @@ odoo.define('website_event.editor', function (require) { "use strict"; var core = require('web.core'); -var wUtils = require('website.utils'); +var Dialog = require('web.Dialog'); +var time = require('web.time'); var WebsiteNewMenu = require('website.newMenu'); - var _t = core._t; +var EventCreateDialog = Dialog.extend({ + xmlDependencies: Dialog.prototype.xmlDependencies.concat(['/website_event/static/src/xml/event_create.xml']), + template: 'website_event.event_create_dialog', + events: _.extend({}, Dialog.prototype.events, { + 'change select[name="event_location"]': '_onLocationChanged', + 'click .input-group-append': '_onDatetimeClicked', + }), + cssLibs: [ + '/web/static/lib/daterangepicker/daterangepicker.css', + ], + jsLibs: [ + '/web/static/lib/daterangepicker/daterangepicker.js', + '/web/static/src/legacy/js/libs/daterangepicker.js', + ], + + + /** + * @override + * @param {Object} parent + * @param {Object} options + */ + init: function (parent, options) { + options = _.defaults(options || {}, { + title: _t("New Event"), + size: 'medium', + buttons: [ + { + text: _t("Create"), + classes: 'btn-primary', + click: this._onClickCreate.bind(this), + }, + { + text: _t("Discard"), + close: true + }, + ] + }); + this.eventStart = moment(); + this.eventEnd = moment().add(1, "d"); + this._super(parent, options); + }, + + /** + * @override + */ + start: function () { + var self = this; + return this._super.apply(this, arguments).then(() => { + // stat / end datetimes widgets + self.$('input.daterange-input').each(function () { + self._initDateRangePicker($(this)); + }); + // address select2 configuration + self.$('input.o_wevent_js_address_id').select2(self._getSelect2AddressConfig()); + }); + }, + + /** + * @param {*} errors + */ + _display_errors: function (errors) { + this.$("p.text-danger").toggleClass('d-none', true); + for (let i = 0; i < errors.length; i++) { + this.$("#" + errors[i] + " p.text-danger").toggleClass('d-none', false); + } + }, + + _getSelect2AddressConfig: function () { + var self = this; + return { + allowClear: true, + formatNoMatches: false, + multiple: false, + selection_data: false, + width: '100%', + + createSearchChoice: function (name, data) { + var addedPartner = $(this.opts.element).select2('data'); + if (_.filter(_.union(addedPartner, data), function (partner) { + return partner.text.toLowerCase().localeCompare(name.toLowerCase()) === 0; + }).length === 0) { + return { + create: true, + id: _.uniqueId('address_'), + name: name, + text: _.str.sprintf(_t('Create "%s"'), name), + }; + } + }, + fill_data: function (query, data) { + var that = this; + var partners = {results: []}; + _.each(data, function (partner) { + var contact_address = partner.contact_address.replace(/[\n]+/g, '').trim(); + if (contact_address && that.matcher(query.term, contact_address)) { + partners.results.push({ + id: partner.id, + text: contact_address, + }); + } + }); + query.callback(partners); + }, + formatSelection: function (data) { + if (data.name) { + data.text = data.name; + } + return data.text; + }, + query: function (query) { + var that = this; + // fetch data only once and store it + if (!this.selection_data) { + self._rpc({ + model: 'res.partner', + method: 'search_read', + fields: ['contact_address'], + domain: [], + }).then(function (data) { + that.fill_data(query, data); + that.selection_data = data; + }); + } else { + this.fill_data(query, this.selection_data); + } + } + } + }, + + _getSelect2AddressValues: function () { + var select2Value = this.$('input.o_wevent_js_address_id').select2('data'); + if (select2Value) { + if (select2Value.create) { + return [0, {'name': select2Value.name}]; + } else { + return [select2Value.id, {}]; + } + } + return []; + }, + + /** + * + * @param {*} $dateGroup + */ + _initDateRangePicker: function ($dateGroup) { + var minDate = moment().subtract(1, "d"); + var maxDate = moment().add(200, "y"); + var self = this; + var textDirection = _t.database.parameters.direction; + + $dateGroup.daterangepicker({ + // dates + endDate: this.eventEnd, + maxDate: maxDate, + minDate: minDate, + startDate: this.eventStart, + // display + locale: { + direction: textDirection, + format: time.getLangDatetimeFormat().replace(':ss', ''), + separator: ' 🠖 ', + applyLabel: _t('Apply'), + cancelLabel: _t('Cancel'), + weekLabel: 'W', + customRangeLabel: _t('Custom Range'), + daysOfWeek: moment.weekdaysMin(), + monthNames: moment.monthsShort(), + firstDay: moment.localeData().firstDayOfWeek() + }, + opens: 'left', + timePicker: true, + timePicker24Hour: true, + viewDate: moment(new Date()).hours(minDate.hours()).minutes(minDate.minutes()).seconds(minDate.seconds()).milliseconds(minDate.milliseconds()), + }, function (start, end, label) { + self.eventStart = start; + self.eventEnd = end; + }); + }, + /** + * @private + */ + _prepareFormValues: function () { + return { + address_values: this._getSelect2AddressValues(), + event_start: this.eventStart, + event_end: this.eventEnd, + location: this.$('select[name=event_location]').val(), + name: this.$('input[name=name]').val().trim(), + }; + }, + /** + * @private + * @param {*} values + */ + _validateForm: function (values) { + var errors = []; + if (!values.name){ + errors.push('name'); + } + if (values.location === 'on_site' && !values.address_values.length) { + errors.push('address'); + } + if (!values.event_start || !values.event_end) { + errors.push('event_dates'); + } + return errors; + }, + + /** + * @private + */ + _submitForm: function () { + var self = this; + var eventValues = this._prepareFormValues(); + var errors = this._validateForm(eventValues) + console.log(eventValues, errors); + if (errors.length) { + this._display_errors(errors); + return; + } + return this._rpc({ + route: '/event/add_event', + params: eventValues, + }).then((url) => { + window.location.href = url; + return new Promise(function () {}); + }); + }, + + /** + * @private + */ + _onClickCreate: function () { + return this._submitForm(); + }, + + /** + * @private + * @param {*} ev + */ + _onLocationChanged: function (ev) { + this.$('.show_visibility_address').toggleClass('d-none', ev.target.value === 'online'); + }, +}); + WebsiteNewMenu.include({ actions: _.extend({}, WebsiteNewMenu.prototype.actions || {}, { new_event: '_createNewEvent', @@ -25,25 +271,12 @@ WebsiteNewMenu.include({ */ _createNewEvent: function () { var self = this; - return wUtils.prompt({ - id: "editor_new_event", - window_title: _t("New Event"), - input: _t("Event Name"), - }).then(function (result) { - var eventName = result.val; - if (!eventName) { - return; - } - return self._rpc({ - route: '/event/add_event', - params: { - event_name: eventName, - }, - }).then(function (url) { - window.location.href = url; - return new Promise(function () {}); - }); + var def = new Promise(function (resolve) { + var dialog = new EventCreateDialog(self, {}); + dialog.open(); + dialog.on('closed', self, resolve); }); + return def; }, }); }); diff --git a/addons/website_event/static/src/xml/event_create.xml b/addons/website_event/static/src/xml/event_create.xml new file mode 100644 index 00000000000..52cc5dc3339 --- /dev/null +++ b/addons/website_event/static/src/xml/event_create.xml @@ -0,0 +1,37 @@ + + + +
+
+ +
+ +
+

Please fill in this field

+
+
+ +
+ +
+
+
+ +
+ +
+

Please fill in this field

+
+
+ +
+ +
+

Please fill in this field

+
+
+
+
diff --git a/addons/website_event/static/tests/tours/website_event.js b/addons/website_event/static/tests/tours/website_event.js index 0a3a038705d..56cc9937ee8 100644 --- a/addons/website_event/static/tests/tours/website_event.js +++ b/addons/website_event/static/tests/tours/website_event.js @@ -4,6 +4,7 @@ odoo.define("website_event.tour", function (require) { const {_t} = require("web.core"); const {Markup} = require('web.utils'); var tour = require("web_tour.tour"); + var time = require('web.time'); tour.register("website_event_tour", { test: true, @@ -17,11 +18,16 @@ odoo.define("website_event.tour", function (require) { content: _t("Click here to create a new event."), position: "bottom", }, { - trigger: '.modal-dialog #editor_new_event input[type=text]', + trigger: '.modal-dialog #editor_new_event input[name=name]', content: Markup(_t("Create a name for your new event and click \"Continue\". e.g: Technical Training")), + run: 'text Technical Training', position: "left", }, { - trigger: '.modal-footer button.btn-primary.btn-continue', + trigger: '.modal-dialog #editor_new_event input[name=event_start_end]', + content: _t("Pick a Start date for your event"), + run: 'text ' + moment().format(time.getLangDatetimeFormat()) + ' - ' + moment().add(1, "d").format(time.getLangDatetimeFormat()), + }, { + trigger: '.modal-footer button.btn-primary', extra_trigger: '#editor_new_event input[type=text][value!=""]', content: Markup(_t("Click Continue to create the event.")), position: "right", diff --git a/addons/website_event/views/event_tag_category_views.xml b/addons/website_event/views/event_tag_category_views.xml index e1e22ed80f8..1d72a1eaaf7 100644 --- a/addons/website_event/views/event_tag_category_views.xml +++ b/addons/website_event/views/event_tag_category_views.xml @@ -17,7 +17,7 @@ event.tag.category - + diff --git a/addons/website_event/views/event_templates_list.xml b/addons/website_event/views/event_templates_list.xml index 4b69241ea2d..af59890f201 100644 --- a/addons/website_event/views/event_templates_list.xml +++ b/addons/website_event/views/event_templates_list.xml @@ -47,7 +47,25 @@
Events -