Skip to content
Snippets Groups Projects
Commit ddccd33b authored by Thibault Delavallée's avatar Thibault Delavallée
Browse files

[IMP] website_slides: improve upload slide screen

Slide upload access is a bit cleaned. A can_publish field is added controlling
who can publish slides. Currently website publishers are allowed to publish
content. Not publishers people allowed to upload cannot publish their own
content. It stays in a submitted non published state.

This commit is linked to task ID 1937411 and PR #30847.
parent b91add89
No related branches found
No related tags found
No related merge requests found
......@@ -293,16 +293,29 @@ class WebsiteSlides(http.Controller):
values['category_id'] = post['category_id'][0]
# handle exception during creation of slide and sent error notification to the client
# otherwise client slide create dialog box continue processing even server fail to create a slide.
# otherwise client slide create dialog box continue processing even server fail to create a slide
try:
slide_id = request.env['slide.slide'].create(values)
channel = request.env['slide.channel'].browse(values['channel_id'])
can_upload = channel.can_upload
can_publish = channel.can_publish
except (UserError, AccessError) as e:
_logger.error(e)
return {'error': e.name}
else:
if not can_upload:
return {'error': _('You cannot upload on this channel.')}
try:
values['user_id'] = request.env.uid
values['website_published'] = values.get('website_published', False) and can_publish
slide = request.env['slide.slide'].sudo().create(values)
except (UserError, AccessError) as e:
_logger.error(e)
return {'error': e.name}
except Exception as e:
_logger.error(e)
return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s') % e}
return {'url': "/slides/slide/%s" % (slide_id.id)}
return {'url': "/slides/slide/%s" % (slide.id)}
@http.route(['/slides/tag/search_read'], type='json', auth='user', methods=['POST'], website=True)
def slide_tag_search_read(self, fields, domain):
......
......@@ -106,6 +106,7 @@ class Channel(models.Model):
string='Upload Groups', help="Groups allowed to upload presentations in this channel. If void, every user can upload.")
# not stored access fields, depending on each user
can_upload = fields.Boolean('Can Upload', compute='_compute_access')
can_publish = fields.Boolean('Can Publish', compute='_compute_access')
@api.depends('custom_slide_id', 'promote_strategy', 'slide_ids.likes',
'slide_ids.total_views', "slide_ids.date_published")
......@@ -164,6 +165,7 @@ class Channel(models.Model):
@api.depends('visibility', 'partner_ids', 'upload_group_ids')
def _compute_access(self):
self.can_upload = not self.env.user.share and (not self.upload_group_ids or bool(self.upload_group_ids & self.env.user.groups_id))
self.can_publish = self.can_upload and self.env.user.has_group('website.group_website_publisher')
@api.multi
@api.depends('name')
......
......@@ -92,6 +92,7 @@ class Slide(models.Model):
# description
name = fields.Char('Title', required=True, translate=True)
active = fields.Boolean(default=True)
user_id = fields.Many2one('res.users', string='Uploaded by', default=lambda self: self.env.uid)
description = fields.Text('Description', translate=True)
channel_id = fields.Many2one('slide.channel', string="Channel", required=True)
category_id = fields.Many2one('slide.category', string="Category", domain="[('channel_id', '=', channel_id)]")
......@@ -218,6 +219,12 @@ class Slide(models.Model):
@api.model
def create(self, values):
# Do not publish slide if user has not publisher rights
channel = self.env['slide.channel'].browse(values['channel_id'])
if not channel.can_publish:
values['website_published'] = False
values['date_published'] = False
if not values.get('index_content'):
values['index_content'] = values.get('description')
if values.get('slide_type') == 'infographic' and not values.get('image'):
......@@ -228,15 +235,18 @@ class Slide(models.Model):
doc_data = self._parse_document_url(values['url']).get('values', dict())
for key, value in doc_data.items():
values.setdefault(key, value)
# Do not publish slide if user has not publisher rights
if not self.user_has_groups('website.group_website_publisher'):
values['website_published'] = False
slide = super(Slide, self).create(values)
slide._post_publication()
if slide.website_published:
slide._post_publication()
return slide
@api.multi
def write(self, values):
if values.get('website_published') and any(not slide.channel_id.can_publish for slide in self):
values.pop('website_published')
if values.get('url') and values['url'] != self.url:
doc_data = self._parse_document_url(values['url']).get('values', dict())
for key, value in doc_data.items():
......
......@@ -24,11 +24,14 @@ var SlideDialog = Widget.extend({
/**
* @override
* @param {Object} el
* @param {number} channel_id
* @param {Object} data holding channelId and optionally upload and publish control parameters
*/
init: function (el, channelID) {
this._super(el, channelID);
this.channel_id = parseInt(channelID, 10);
init: function (el, data) {
this._super(el, data);
this.channelId = parseInt(data.channelId, 10);
this.canUpload = data.canUpload === 'True';
this.canPublish = data.canPublish === 'True';
console.log(this.channelId, this.canUpload, this.canPublish);
this.file = {};
this.index_content = '';
},
......@@ -56,7 +59,7 @@ var SlideDialog = Widget.extend({
return this._rpc({
model: 'slide.slide',
method: 'search_count',
args: [[['channel_id', '=', self.channel_id], ['name', '=', fileName]]],
args: [[['channel_id', '=', self.channelId], ['name', '=', fileName]]],
});
},
/**
......@@ -156,7 +159,7 @@ var SlideDialog = Widget.extend({
route: '/slides/category/search_read',
params: {
fields: ['name'],
domain: [['channel_id', '=', self.channel_id]],
domain: [['channel_id', '=', self.channelId]],
}
});
}));
......@@ -224,7 +227,7 @@ var SlideDialog = Widget.extend({
_getValue: function () {
var canvas = this.$('#data_canvas')[0],
values = {
'channel_id': this.channel_id || '',
'channel_id': this.channelId || '',
'name': this.$('#name').val(),
'url': this.$('#url').val(),
'description': this.$('#description').val(),
......@@ -418,7 +421,7 @@ var SlideDialog = Widget.extend({
var self = this,
value = {
'url': $(ev.target).val(),
'channel_id': self.channel_id
'channel_id': self.channelId
};
this.$('.alert-warning').remove();
this.is_valid_url = false;
......@@ -454,7 +457,7 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
start: function () {
// Automatically open the upload dialog if requested from query string
if ($.deparam.querystring().enable_slide_upload !== undefined) {
this._openDialog(this.$el.attr('channel_id'));
this._openDialog(this.$el);
}
return this._super.apply(this, arguments);
},
......@@ -463,8 +466,9 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
// Private
//--------------------------------------------------------------------------
_openDialog: function (channelID) {
new SlideDialog(this, channelID).appendTo(document.body);
_openDialog: function ($element) {
var data = $element.data();
new SlideDialog(this, data).appendTo(document.body);
},
//--------------------------------------------------------------------------
......@@ -476,7 +480,7 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
* @param {Event} ev
*/
_onUploadClick: function (ev) {
this._openDialog($(ev.currentTarget).attr('channel_id'));
this._openDialog($(ev.currentTarget));
},
});
});
......@@ -67,8 +67,9 @@
</main>
<footer class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Discard</button>
<button type="button" data-loading-text="Loading..." class="btn btn-primary save">Save as Draft</button>
<button type="button" data-loading-text="Loading..." data-published="true" class="btn btn-primary save">Save and Publish</button>
<button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; widget.canPublish" class="btn btn-primary save">Save as Draft</button>
<button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; ! widget.canPublish" class="btn btn-primary save">Submit</button>
<button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; widget.canPublish" data-published="true" class="btn btn-primary save">Publish</button>
</footer>
</div>
</div>
......
......@@ -108,9 +108,12 @@
<t t-if="category">
/ <a t-attf-href="/slides/#{slug(channel)}/category/#{slug(category)}" t-esc="category.name"/>
</t>
<!-- Public user has not right to create/write on slide -->
<t t-if="channel.can_upload">
<a role="button" class="btn btn-primary oe_slide_js_upload" title="Upload Presentation" t-attf-channel_id="#{channel.id}" aria-label="Upload Presentation" href="#">
<a role="button" class="btn btn-primary oe_slide_js_upload" title="Upload Presentation"
aria-label="Upload Presentation" href="#"
t-att-data-channel-id="channel.id"
t-att-data-can-upload="channel.can_upload"
t-att-data-can-publish="channel.can_publish">
<i class="fa fa-cloud-upload"></i> Upload
</a>
</t>
......@@ -286,7 +289,7 @@
</p>
<p>
<!-- Public user has not right to create/write on slide-->
<a role="button" t-if="channel.can_upload" class="btn btn-primary oe_slide_js_upload" t-attf-channel_id="#{channel.id}" aria-label="Upload Presentation" title="Upload Presentation" href="#">
<a role="button" t-if="channel.can_upload" class="btn btn-primary oe_slide_js_upload" t-attf-channel-id="#{channel.id}" aria-label="Upload Presentation" title="Upload Presentation" href="#">
<i class="fa fa-cloud-upload"></i> Upload
</a>
</p>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment