[IMP] website_event(_track): improve website and track menus behavior
PURPOSE Before this commit to activate the sub-menu, the tracks and the track proposal you had to do it on the event form view. After this commit you'll have to go on the event website page to change those options (through the customize dropdown) SPECIFICATION Remove the 'website_menu' / 'website_track' / 'website_track_proposal' from the event form view and create a toggle option in the customize dropdown on the event website page instead. LINKS Task ID : 2198660 PR : #46659
This commit is contained in:
@@ -70,12 +70,16 @@ class Event(models.Model):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
res = super(Event, self).create(vals)
|
||||
res._update_website_menus(vals)
|
||||
res._update_website_menus()
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
menu_activated = self.filtered(lambda event: event.website_menu)
|
||||
menu_deactivated = self.filtered(lambda event: not event.website_menu)
|
||||
res = super(Event, self).write(vals)
|
||||
self._update_website_menus(vals)
|
||||
menu_to_deactivate = menu_activated.filtered(lambda event: not event.website_menu)
|
||||
menu_to_activate = menu_deactivated.filtered(lambda event: event.website_menu)
|
||||
(menu_to_activate | menu_to_deactivate)._update_website_menus()
|
||||
return res
|
||||
|
||||
def _get_menu_entries(self):
|
||||
@@ -88,19 +92,19 @@ class Event(models.Model):
|
||||
(_('Register'), '/event/%s/register' % slug(self), False),
|
||||
]
|
||||
|
||||
def _update_website_menus(self, vals):
|
||||
def _update_website_menus(self):
|
||||
for event in self:
|
||||
if 'website_menu' in vals:
|
||||
if event.menu_id and not event.website_menu:
|
||||
event.menu_id.unlink()
|
||||
elif event.website_menu and not event.menu_id:
|
||||
root_menu = self.env['website.menu'].create({'name': event.name, 'website_id': event.website_id.id})
|
||||
event.menu_id = root_menu
|
||||
for sequence, (name, url, xml_id) in enumerate(event._get_menu_entries()):
|
||||
event._create_menu(sequence, name, url, xml_id)
|
||||
if event.menu_id and not event.website_menu:
|
||||
event.menu_id.unlink()
|
||||
elif event.website_menu and not event.menu_id:
|
||||
root_menu = self.env['website.menu'].create({'name': event.name, 'website_id': event.website_id.id})
|
||||
event.menu_id = root_menu
|
||||
for sequence, (name, url, xml_id) in enumerate(event._get_menu_entries()):
|
||||
event._create_menu(sequence, name, url, xml_id)
|
||||
|
||||
def _create_menu(self, sequence, name, url, xml_id):
|
||||
if not url:
|
||||
self.env['ir.ui.view'].search([('name', '=', name + ' ' + self.name)]).unlink()
|
||||
newpath = self.env['website'].new_page(name + ' ' + self.name, template=xml_id, ispage=False)['url']
|
||||
url = "/event/" + slug(self) + "/page/" + newpath[1:]
|
||||
menu = self.env['website.menu'].create({
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
odoo.define('website_event.set_customize_options', function (require) {
|
||||
"use strict";
|
||||
|
||||
var CustomizeMenu = require('website.customizeMenu');
|
||||
var publicWidget = require('web.public.widget');
|
||||
|
||||
var EventSpecificOptions = publicWidget.Widget.extend({
|
||||
template: 'website_event.customize_options',
|
||||
xmlDependencies: ['/website_event/static/src/xml/customize_options.xml'],
|
||||
events: {
|
||||
'change #display-website-menu': '_onDisplaySubmenuChange',
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$submenuInput = this.$('#display-website-menu');
|
||||
this.modelName = this._getEventObject().model;
|
||||
this.eventId = this._getEventObject().id;
|
||||
this._initCheckbox();
|
||||
},
|
||||
|
||||
_initCheckbox: function () {
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'read',
|
||||
args: [[this.eventId], ['website_menu', 'website_url']],
|
||||
}).then((data) => {
|
||||
if (data[0]['website_menu']) {
|
||||
this.$submenuInput.attr('checked', 'checked');
|
||||
}
|
||||
this.eventUrl = data[0]['website_url'];
|
||||
});
|
||||
},
|
||||
|
||||
_onDisplaySubmenuChange: function (ev) {
|
||||
var checkboxValue = this.$submenuInput.is(':checked');
|
||||
this._toggleSubmenuDisplay(checkboxValue);
|
||||
},
|
||||
|
||||
_toggleSubmenuDisplay: function (val) {
|
||||
var self = this;
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'toggle_website_menu',
|
||||
args: [[this.eventId], val],
|
||||
}).then(function () {
|
||||
self._reloadEventPage();
|
||||
});
|
||||
},
|
||||
|
||||
_reloadEventPage: function () {
|
||||
window.location = this.eventUrl;
|
||||
},
|
||||
|
||||
_getEventObject: function() {
|
||||
var repr = $('html').data('main-object');
|
||||
var m = repr.match(/(.+)\((\d+),(.*)\)/);
|
||||
return {
|
||||
model: m[1],
|
||||
id: m[2] | 0,
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
CustomizeMenu.include({
|
||||
_getEventObject: function() {
|
||||
var repr = $('html').data('main-object');
|
||||
var m = repr.match(/(.+)\((\d+),(.*)\)/);
|
||||
return {
|
||||
model: m[1],
|
||||
id: m[2] | 0,
|
||||
};
|
||||
},
|
||||
|
||||
_loadCustomizeOptions: function () {
|
||||
var self = this;
|
||||
var def = this._super.apply(this, arguments);
|
||||
return def.then(function () {
|
||||
if (!self.__eventOptionsLoaded && self._getEventObject().model === 'event.event') {
|
||||
self.__eventOptionsLoaded = true;
|
||||
self.eventOptions = new EventSpecificOptions(self);
|
||||
self.eventOptions.insertAfter(self.$el.find('.dropdown-divider:first()'));
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
EventSpecificOptions: EventSpecificOptions,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="website_event.customize_options" id="event_options">
|
||||
<li class="dropdown-header">Event Specific</li>
|
||||
<a href="#" name="display-website-menu" class="dropdown-item" role="menuitem">
|
||||
<label class="o_switch" for="display-website-menu">
|
||||
<input id="display-website-menu" type="checkbox"/>
|
||||
<span/>
|
||||
Event Sub-menu
|
||||
</label>
|
||||
</a>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -15,6 +15,7 @@
|
||||
<script type="text/javascript" src="/website_event/static/src/js/website_geolocation.js"></script>
|
||||
<script type="text/javascript" src="/website_event/static/src/js/website_event.js"></script>
|
||||
<script type="text/javascript" src="/website_event/static/src/js/website_event_ticket_details.js"></script>
|
||||
<script type="text/javascript" src="/website_event/static/src/js/website_event_set_customize_options.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class Event(models.Model):
|
||||
for event in self:
|
||||
event.sponsor_count = result.get(event.id, 0)
|
||||
|
||||
@api.depends('event_type_id', 'website_menu')
|
||||
@api.depends('event_type_id', 'website_menu', 'website_track_proposal')
|
||||
def _compute_website_track(self):
|
||||
""" Explicitly checks that event_type has changed before copying its value
|
||||
on the event itself. Changing website_menu trigger should not mess with the
|
||||
@@ -63,8 +63,10 @@ class Event(models.Model):
|
||||
for event in self:
|
||||
if event.event_type_id and event.event_type_id != event._origin.event_type_id:
|
||||
event.website_track = event.event_type_id.website_track
|
||||
elif not event.website_menu or not event.website_track:
|
||||
elif not event.website_menu:
|
||||
event.website_track = False
|
||||
elif event.website_track_proposal and not event.website_track:
|
||||
event.website_track = True
|
||||
|
||||
@api.depends('event_type_id', 'website_track')
|
||||
def _compute_website_track_proposal(self):
|
||||
@@ -74,57 +76,46 @@ class Event(models.Model):
|
||||
elif not event.website_track:
|
||||
event.website_track_proposal = False
|
||||
|
||||
@api.onchange('website_track_proposal')
|
||||
def _onchange_website_track_proposal(self):
|
||||
""" Keep an explicit onchange for tick / untick of website_track_proposal.
|
||||
Indeed otherwise you have a loop of dependencies between website_track and
|
||||
website_track_proposal
|
||||
|
||||
* untick website_track: website_track_proposal = False (done in _compute_website_track_proposal)
|
||||
* tick website_track: no effect
|
||||
* untick website_track_proposal: no effect
|
||||
* tick website_track_proposa: website_track = True
|
||||
|
||||
It would be complicated to write in computed fields, as they depend on
|
||||
each other, on cache and current values, ...
|
||||
|
||||
It is therefore simpler to keep an onchange: when ticking website_track_proposal
|
||||
set website_track as True in interface.
|
||||
"""
|
||||
for event in self:
|
||||
if event.website_track_proposal and not event.website_track:
|
||||
event.website_track = True
|
||||
|
||||
@api.depends('track_ids.tag_ids', 'track_ids.tag_ids.color')
|
||||
def _compute_tracks_tag_ids(self):
|
||||
for event in self:
|
||||
event.tracks_tag_ids = event.track_ids.mapped('tag_ids').filtered(lambda tag: tag.color != 0).ids
|
||||
|
||||
def _update_website_menus(self, vals):
|
||||
super(Event, self)._update_website_menus(vals)
|
||||
def _update_website_menus(self):
|
||||
super(Event, self)._update_website_menus()
|
||||
for event in self:
|
||||
if 'website_track' in vals:
|
||||
if vals['website_track'] and not event.track_menu_ids:
|
||||
for sequence, (name, url, xml_id, menu_type) in enumerate(event._get_track_menu_entries()):
|
||||
menu = super(Event, event)._create_menu(sequence, name, url, xml_id)
|
||||
event.env['website.event.menu'].create({
|
||||
'menu_id': menu.id,
|
||||
'event_id': event.id,
|
||||
'menu_type': menu_type,
|
||||
})
|
||||
elif event.track_menu_ids and not vals['website_track']:
|
||||
event.track_menu_ids.mapped('menu_id').unlink()
|
||||
if 'website_track_proposal' in vals:
|
||||
if vals['website_track_proposal'] and not event.track_proposal_menu_ids:
|
||||
for sequence, (name, url, xml_id, menu_type) in enumerate(event._get_track_proposal_menu_entries()):
|
||||
menu = super(Event, event)._create_menu(sequence, name, url, xml_id)
|
||||
event.env['website.event.menu'].create({
|
||||
'menu_id': menu.id,
|
||||
'event_id': event.id,
|
||||
'menu_type': menu_type,
|
||||
})
|
||||
elif event.track_proposal_menu_ids and not vals['website_track_proposal']:
|
||||
event.track_proposal_menu_ids.mapped('menu_id').unlink()
|
||||
if event.website_track and not event.track_menu_ids:
|
||||
for sequence, (name, url, xml_id, menu_type) in enumerate(event._get_track_menu_entries()):
|
||||
menu = super(Event, event)._create_menu(sequence, name, url, xml_id)
|
||||
event.env['website.event.menu'].create({
|
||||
'menu_id': menu.id,
|
||||
'event_id': event.id,
|
||||
'menu_type': menu_type,
|
||||
})
|
||||
elif not event.website_track:
|
||||
event.track_menu_ids.mapped('menu_id').unlink()
|
||||
if event.website_track_proposal and not event.track_proposal_menu_ids:
|
||||
for sequence, (name, url, xml_id, menu_type) in enumerate(event._get_track_proposal_menu_entries()):
|
||||
menu = super(Event, event)._create_menu(sequence, name, url, xml_id)
|
||||
event.env['website.event.menu'].create({
|
||||
'menu_id': menu.id,
|
||||
'event_id': event.id,
|
||||
'menu_type': menu_type,
|
||||
})
|
||||
elif not event.website_track_proposal:
|
||||
event.track_proposal_menu_ids.mapped('menu_id').unlink()
|
||||
|
||||
def write(self, values):
|
||||
track_activated = self.filtered(lambda event: event.website_track)
|
||||
track_deactivated = self.filtered(lambda event: not event.website_track)
|
||||
track_proposal_activated = self.filtered(lambda event: event.website_track_proposal)
|
||||
track_proposal_deactivated = self.filtered(lambda event: not event.website_track_proposal)
|
||||
super(Event, self).write(values)
|
||||
to_deactivate = track_activated.filtered(lambda event: not event.website_track)
|
||||
to_activate = track_deactivated.filtered(lambda event: event.website_track)
|
||||
track_proposal_to_deactivate = track_proposal_activated.filtered(lambda event: not event.website_track_proposal)
|
||||
track_proposal_to_activate = track_proposal_deactivated.filtered(lambda event: event.website_track_proposal)
|
||||
(to_activate | to_deactivate | track_proposal_to_activate | track_proposal_to_deactivate)._update_website_menus()
|
||||
|
||||
def _get_track_menu_entries(self):
|
||||
self.ensure_one()
|
||||
@@ -137,3 +128,12 @@ class Event(models.Model):
|
||||
self.ensure_one()
|
||||
res = [(_('Talk Proposals'), '/event/%s/track_proposal' % slug(self), False, 'track_proposal')]
|
||||
return res
|
||||
|
||||
def toggle_website_menu(self, val):
|
||||
self.website_menu = val
|
||||
|
||||
def toggle_website_track(self, val):
|
||||
self.website_track = val
|
||||
|
||||
def toggle_website_track_proposal(self, val):
|
||||
self.website_track_proposal = val
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
odoo.define('website_event_track.set_customize_options', function (require) {
|
||||
"use strict";
|
||||
|
||||
var EventSpecificOptions = require('website_event.set_customize_options').EventSpecificOptions;
|
||||
|
||||
EventSpecificOptions.include({
|
||||
xmlDependencies: (EventSpecificOptions.prototype.xmlDependencies || [])
|
||||
.concat([
|
||||
'/website_event_track/static/src/xml/customize_options.xml',
|
||||
]),
|
||||
|
||||
events: _.extend({}, EventSpecificOptions.prototype.events, {
|
||||
'change #display-showcase-talks': '_onDisplayTalksChange',
|
||||
'change #allow-talk-proposal': '_onAllowTalkProposalChange',
|
||||
}),
|
||||
|
||||
start: function () {
|
||||
this.$displayTalksInput = this.$('#display-showcase-talks');
|
||||
this.$allowTalksInput = this.$('#allow-talk-proposal');
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
_initCheckbox: function () {
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'read',
|
||||
args: [[this.eventId], ['website_menu', 'website_url', 'website_track', 'website_track_proposal']],
|
||||
}).then((data) => {
|
||||
if (data[0]['website_track']) {
|
||||
this.$displayTalksInput.attr('checked', 'checked');
|
||||
}
|
||||
if (data[0]['website_track_proposal']) {
|
||||
this.$allowTalksInput.attr('checked', 'checked');
|
||||
}
|
||||
if (data[0]['website_menu']) {
|
||||
this.$submenuInput.attr('checked', 'checked');
|
||||
} else {
|
||||
this.$displayTalksInput.closest('a').addClass('d-none');
|
||||
this.$allowTalksInput.closest('a').addClass('d-none');
|
||||
}
|
||||
this.eventUrl = data[0]['website_url'];
|
||||
});
|
||||
},
|
||||
|
||||
_onAllowTalkProposalChange: function () {
|
||||
var checkboxValue = this.$allowTalksInput.is(':checked');
|
||||
this._toggleTalkProposal(checkboxValue);
|
||||
},
|
||||
|
||||
_toggleTalkProposal: function (val) {
|
||||
var self = this;
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'toggle_website_track_proposal',
|
||||
args: [[this.eventId], val],
|
||||
}).then(function () {
|
||||
self._reloadEventPage();
|
||||
});
|
||||
},
|
||||
|
||||
_onDisplayTalksChange: function () {
|
||||
var checkboxValue = this.$displayTalksInput.is(':checked');
|
||||
this._toggleDisplayTalks(checkboxValue);
|
||||
},
|
||||
|
||||
_toggleDisplayTalks: function (val) {
|
||||
var self = this;
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'toggle_website_track',
|
||||
args: [[this.eventId], val],
|
||||
}).then(function () {
|
||||
self._reloadEventPage();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-extend="website_event.customize_options">
|
||||
<t t-jquery="a[name='display-website-menu']" t-operation="after">
|
||||
<a href="#" name="display-showcase-talks" class="dropdown-item" role="menuitem">
|
||||
<label class="o_switch" for="display-showcase-talks">
|
||||
<input id="display-showcase-talks" type="checkbox"/>
|
||||
<span/>
|
||||
Showcase Talks
|
||||
</label>
|
||||
</a>
|
||||
<a href="#" name="allow-talk-proposal" class="dropdown-item" role="menuitem">
|
||||
<label class="o_switch" for="allow-talk-proposal">
|
||||
<input id="allow-talk-proposal" type="checkbox"/>
|
||||
<span/>
|
||||
Allow Talks Proposals
|
||||
</label>
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -5,6 +5,7 @@
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/website_event_track/static/src/css/website_event_track.css"/>
|
||||
<script type="text/javascript" src="/website_event_track/static/src/js/website_event_track.js"></script>
|
||||
<script type="text/javascript" src="/website_event_track/static/src/js/website_event_track_set_customize_options.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user