From 813943c8bcabcb45eabe56d8c56664427daf9f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 5 Mar 2019 15:57:39 +0000 Subject: [PATCH 1/9] [IMP] website_slides: improve demo related to quizzes Purpose is to have a bit more demo data allowing to test quizzes and see how they behave. Notably * have more than one question in existing quizzes to check answer validation more in-depth; * have more than 2 answers to check answer highlighting more in-depth; * clean a bit user related demo for channels and slides; Commit linked to task ID 1941250 and PR #31512. --- .../website_slides/data/slide_slide_demo.xml | 62 ++++++++++++++++--- .../website_slides/data/slide_user_demo.xml | 35 +++++++++-- 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/addons/website_slides/data/slide_slide_demo.xml b/addons/website_slides/data/slide_slide_demo.xml index 163aa3182b5..852d472425a 100644 --- a/addons/website_slides/data/slide_slide_demo.xml +++ b/addons/website_slides/data/slide_slide_demo.xml @@ -30,14 +30,14 @@ 5 1 - A summary of know-how: how and what. + Interesting informations about home gardening. Keep it close ! Tree Infographic - 1 + 1 infographic @@ -152,6 +152,16 @@ We had a little chat with Harry Potted, sure he had interesting things to say ! + + Know More Link 1 + http://www.example.com + + + + Know More Link 2 + http://www.example.com + + Do you think Harry Potted has a good name ? @@ -166,6 +176,25 @@ + + Did you read the whole article ? + + + + Yes + + + + + No + + + + + What was the question again ? + + + 3 Main Methodologies 6 @@ -204,29 +233,48 @@ A summary of know-how: how and what. - Example Link 1 + Trees Classification Link 1 http://www.example.com - Example Link 2 + Trees Classification Link 2 http://www.example.com - Do you want to reply correctly ? + Do you make beams out of lemon trees ? Yes - + No - + + + Do you make lemons out of beams ? + + + + Yes + + + + + No + + + + + And also bananas + + + A Mighty Forest from Ages 2 diff --git a/addons/website_slides/data/slide_user_demo.xml b/addons/website_slides/data/slide_user_demo.xml index 292091aa918..0bfd991251e 100644 --- a/addons/website_slides/data/slide_user_demo.xml +++ b/addons/website_slides/data/slide_user_demo.xml @@ -33,6 +33,15 @@ 1 + + + + + + + + 1 + @@ -54,26 +63,40 @@ + 1 - - + + - 2 + 1 - + - + + 1 + + + + 1 + + + + + + + 1 + @@ -128,6 +151,7 @@ + @@ -138,7 +162,6 @@ 1 - From 181e6487efa8eec19c6673b67518f314cfc610e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 5 Mar 2019 09:50:30 +0000 Subject: [PATCH 2/9] [IMP] website_slides: reorder controller code to ease understanding Purpose is to order methods and routes according to the main related model. Main routes are above, then tools (sub routes, json routes). Commit linked to task ID 1941250 and PR #31512. --- addons/website_slides/controllers/main.py | 216 +++++++++++----------- 1 file changed, 112 insertions(+), 104 deletions(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index dc87a24dafd..1d2b232c333 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -37,6 +37,9 @@ class WebsiteSlides(WebsiteProfile): if not qs or qs.lower() in loc: yield {'loc': loc} + # SLIDE UTILITIES + # -------------------------------------------------- + def _fetch_slide(self, slide_id): slide = request.env['slide.slide'].browse(int(slide_id)).exists() if not slide: @@ -164,7 +167,7 @@ class WebsiteSlides(WebsiteProfile): return domain # -------------------------------------------------- - # MAIN / SEARCH + # SLIDE.CHANNEL MAIN / SEARCH # -------------------------------------------------- @http.route('/slides', type='http', auth="public", website=True) @@ -416,7 +419,10 @@ class WebsiteSlides(WebsiteProfile): return request.render('website_slides.course_main', values) - @http.route(['/slides/channel/add'], type='http', auth='user', methods=['POST'], website=True) + # SLIDE.CHANNEL UTILS + # -------------------------------------------------- + + @http.route('/slides/channel/add', type='http', auth='user', methods=['POST'], website=True) def slide_channel_create(self, *args, **kw): channel = request.env['slide.channel'].create(self._slide_channel_prepare_values(**kw)) return werkzeug.utils.redirect("/slides/%s" % (slug(channel))) @@ -437,8 +443,51 @@ class WebsiteSlides(WebsiteProfile): 'allow_comment': bool(kw.get('allow_comment')), } + @http.route('/slides/channel/enroll', type='http', auth='public', website=True) + def slide_channel_join_http(self, channel_id): + # TDE FIXME: why 2 routes ? + if not request.website.is_public_user(): + channel = request.env['slide.channel'].browse(int(channel_id)) + channel.action_add_member() + return werkzeug.utils.redirect("/slides/%s" % (slug(channel))) + + @http.route(['/slides/channel/join'], type='json', auth='public', website=True) + def slide_channel_join(self, channel_id): + if request.website.is_public_user(): + return {'error': 'public_user'} + success = request.env['slide.channel'].browse(channel_id).action_add_member() + if not success: + return {'error': 'join_done'} + return success + + @http.route('/slides/channel/resequence', type="json", website=True, auth="user") + def resequence_slides(self, channel_id, slides_data): + """" Reorder the slides within the channel by reassigning their 'sequence' field. + This method also handles slides that are put in a new category (or uncategorized). """ + channel = request.env['slide.channel'].browse(int(channel_id)) + if not channel.can_publish: + return {'error': 'Only the publishers of the channel can edit it'} + + slides = request.env['slide.slide'].search([ + ('id', 'in', [int(key) for key in slides_data.keys()]), + ('channel_id', '=', channel.id) + ]) + + for slide in slides: + slide_key = str(slide.id) + slide.sequence = slides_data[slide_key]['sequence'] + slide.category_id = slides_data[slide_key]['category_id'] if 'category_id' in slides_data[slide_key] else False + + @http.route(['/slides/channel/tag/search_read'], type='json', auth='user', methods=['POST'], website=True) + def slide_channel_tag_search_read(self, fields, domain): + can_create = request.env['slide.channel.tag'].check_access_rights('create', raise_exception=False) + return { + 'read_results': request.env['slide.channel.tag'].search_read(domain, fields), + 'can_create': can_create, + } + # -------------------------------------------------- - # SLIDE.SLIDE CONTOLLERS + # SLIDE.SLIDE MAIN / SEARCH # -------------------------------------------------- @http.route('''/slides/slide/''', type='http', auth="public", website=True) @@ -500,6 +549,9 @@ class WebsiteSlides(WebsiteProfile): response.status_code = status return response + # SLIDE.SLIDE UTILS + # -------------------------------------------------- + @http.route('/slide/html_content/get', type="json", auth="public", website=True) def get_html_content(self, slide_id): slide = request.env['slide.slide'].browse(slide_id) @@ -507,7 +559,61 @@ class WebsiteSlides(WebsiteProfile): 'html_content': slide.html_content } - #SLIDE QUIZ CONTROLLERS + @http.route('/slides/slide//set_completed', website=True, type="http", auth="user") + def slide_set_completed_and_redirect(self, slide, next_slide=None): + self._set_completed_slide(slide) + return werkzeug.utils.redirect("/slides/slide/%s" % (next_slide if next_slide else slide.id)) + + @http.route('/slides/slide/set_completed', website=True, type="json", auth="public") + def slide_set_completed(self, slide_id): + if request.website.is_public_user(): + return {'error': 'public_user'} + fetch_res = self._fetch_slide(slide_id) + if fetch_res.get('error'): + return fetch_res + self._set_completed_slide(fetch_res['slide']) + return { + 'channel_completion': fetch_res['slide'].channel_id.completion + } + + @http.route('/slides/slide/like', type='json', auth="public", website=True) + def slide_like(self, slide_id, upvote): + if request.website.is_public_user(): + return {'error': 'public_user'} + slide_partners = request.env['slide.slide.partner'].sudo().search([ + ('slide_id', '=', slide_id), + ('partner_id', '=', request.env.user.partner_id.id) + ]) + if (upvote and slide_partners.vote == 1) or (not upvote and slide_partners.vote == -1): + return {'error': 'vote_done'} + slide = request.env['slide.slide'].browse(int(slide_id)) + if upvote: + slide.action_like() + else: + slide.action_dislike() + slide.invalidate_cache() + return slide.read(['likes', 'dislikes', 'user_vote'])[0] + + @http.route('/slides/slide/archive', type='json', auth='user', website=True) + def slide_archive(self, slide_id): + """ This route allows channel publishers to archive slides. + It has to be done in sudo mode since only website_publishers can write on slides in ACLs """ + slide = request.env['slide.slide'].browse(int(slide_id)) + if slide.channel_id.can_publish: + slide.sudo().active = False + return True + + return False + + @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True) + def slide_send_share_email(self, slide_id, email): + slide = request.env['slide.slide'].browse(int(slide_id)) + result = slide._send_share_email(email) + return result + + # -------------------------------------------------- + # QUIZZ SECTION + # -------------------------------------------------- @http.route('/slide/quiz/get', type="json", auth="public", website=True) def get_quiz(self, **kw): @@ -573,62 +679,6 @@ class WebsiteSlides(WebsiteProfile): 'error': "You already passed this quiz" } - # -------------------------------------------------- - # SLIDE.SLIDE TOOLS CONTOLLERS - # -------------------------------------------------- - - @http.route('/slides/slide//set_completed', website=True, type="http", auth="user") - def slide_set_completed_and_redirect(self, slide, next_slide=None): - self._set_completed_slide(slide) - return werkzeug.utils.redirect("/slides/slide/%s" % (next_slide if next_slide else slide.id)) - - @http.route('/slides/slide/set_completed', website=True, type="json", auth="public") - def slide_set_completed(self, slide_id): - if request.website.is_public_user(): - return {'error': 'public_user'} - fetch_res = self._fetch_slide(slide_id) - if fetch_res.get('error'): - return fetch_res - self._set_completed_slide(fetch_res['slide']) - return { - 'channel_completion': fetch_res['slide'].channel_id.completion - } - - @http.route('/slides/slide/like', type='json', auth="public", website=True) - def slide_like(self, slide_id, upvote): - if request.website.is_public_user(): - return {'error': 'public_user'} - slide_partners = request.env['slide.slide.partner'].sudo().search([ - ('slide_id', '=', slide_id), - ('partner_id', '=', request.env.user.partner_id.id) - ]) - if (upvote and slide_partners.vote == 1) or (not upvote and slide_partners.vote == -1): - return {'error': 'vote_done'} - slide = request.env['slide.slide'].browse(int(slide_id)) - if upvote: - slide.action_like() - else: - slide.action_dislike() - slide.invalidate_cache() - return slide.read(['likes', 'dislikes', 'user_vote'])[0] - - @http.route('/slides/slide/archive', type='json', auth='user', website=True) - def slide_archive(self, slide_id): - """ This route allows channel publishers to archive slides. - It has to be done in sudo mode since only website_publishers can write on slides in ACLs """ - slide = request.env['slide.slide'].browse(int(slide_id)) - if slide.channel_id.can_publish: - slide.sudo().active = False - return True - - return False - - @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True) - def slide_send_share_email(self, slide_id, email): - slide = request.env['slide.slide'].browse(int(slide_id)) - result = slide._send_share_email(email) - return result - # -------------------------------------------------- # CATEGORY MANAGEMENT # -------------------------------------------------- @@ -663,44 +713,9 @@ class WebsiteSlides(WebsiteProfile): return werkzeug.utils.redirect("/slides/%s" % (slug(channel))) # -------------------------------------------------- - # TOOLS + # SLIDE.UPLOAD # -------------------------------------------------- - @http.route(['/slides/channel/enroll'], type='http', auth='public', website=True) - def slide_channel_join_http(self, channel_id): - # TDE FIXME: why 2 routes ? - if not request.website.is_public_user(): - channel = request.env['slide.channel'].browse(int(channel_id)) - channel.action_add_member() - return werkzeug.utils.redirect("/slides/%s" % (slug(channel))) - - @http.route(['/slides/channel/join'], type='json', auth='public', website=True) - def slide_channel_join(self, channel_id): - if request.website.is_public_user(): - return {'error': 'public_user'} - success = request.env['slide.channel'].browse(channel_id).action_add_member() - if not success: - return {'error': 'join_done'} - return success - - @http.route('/slides/channel/resequence', type="json", website=True, auth="user") - def resequence_slides(self, channel_id, slides_data): - """" Reorder the slides within the channel by reassigning their 'sequence' field. - This method also handles slides that are put in a new category (or uncategorized). """ - channel = request.env['slide.channel'].browse(int(channel_id)) - if not channel.can_publish: - return {'error': 'Only the publishers of the channel can edit it'} - - slides = request.env['slide.slide'].search([ - ('id', 'in', [int(key) for key in slides_data.keys()]), - ('channel_id', '=', channel.id) - ]) - - for slide in slides: - slide_key = str(slide.id) - slide.sequence = slides_data[slide_key]['sequence'] - slide.category_id = slides_data[slide_key]['category_id'] if 'category_id' in slides_data[slide_key] else False - @http.route(['/slides/prepare_preview'], type='json', auth='user', methods=['POST'], website=True) def prepare_preview(self, **data): Slide = request.env['slide.slide'] @@ -780,14 +795,6 @@ class WebsiteSlides(WebsiteProfile): return ['name', 'url', 'tag_ids', 'slide_type', 'channel_id', 'is_preview', 'mime_type', 'datas', 'description', 'image', 'index_content', 'website_published'] - @http.route(['/slides/channel/tag/search_read'], type='json', auth='user', methods=['POST'], website=True) - def slide_channel_tag_search_read(self, fields, domain): - can_create = request.env['slide.channel.tag'].check_access_rights('create', raise_exception=False) - return { - 'read_results': request.env['slide.channel.tag'].search_read(domain, fields), - 'can_create': can_create, - } - @http.route(['/slides/tag/search_read'], type='json', auth='user', methods=['POST'], website=True) def slide_tag_search_read(self, fields, domain): can_create = request.env['slide.tag'].check_access_rights('create', raise_exception=False) @@ -799,6 +806,7 @@ class WebsiteSlides(WebsiteProfile): # -------------------------------------------------- # EMBED IN THIRD PARTY WEBSITES # -------------------------------------------------- + @http.route('/slides/embed/', type='http', auth='public', website=True, sitemap=False) def slides_embed(self, slide_id, page="1", **kw): # Note : don't use the 'model' in the route (use 'slide_id'), otherwise if public cannot access the embedded From 711a48aaa88dafeb186e15b4f9bcca83a31d18e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 5 Mar 2019 11:55:10 +0000 Subject: [PATCH 3/9] [REF] website_slides: clean slide fetch details method and controller Currently there is a tool method on controller allowing to prepare some slide related data. However controllers still add values in the slide dictionary outside of this method, making it non consistent. Let us prepare all side related data in this tool method to simplify code understanding. Commit linked to task ID 1941250 and PR #31512. --- addons/website_slides/controllers/main.py | 53 +++++++++++-------- .../views/website_slides_templates_lesson.xml | 6 +-- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 1d2b232c333..ca01baea917 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -68,26 +68,42 @@ class WebsiteSlides(WebsiteProfile): return True def _get_slide_detail(self, slide): - most_viewed_slides = slide._get_most_viewed_slides(self.SLIDES_PER_ASIDE) - related_slides = slide._get_related_slides(self.SLIDES_PER_ASIDE) + if slide.channel_id.channel_type == 'documentation': + most_viewed_slides = slide._get_most_viewed_slides(self.SLIDES_PER_ASIDE) + related_slides = slide._get_related_slides(self.SLIDES_PER_ASIDE) + uncategorized_slides = request.env['slide.slide'] + else: + most_viewed_slides, related_slides = request.env['slide.slide'], request.env['slide.slide'] + uncategorized_slides = slide.channel_id.slide_ids.filtered(lambda slide: not slide.category_id) + + channel_slides_ids = slide.channel_id.slide_ids.ids + slide_index = channel_slides_ids.index(slide.id) + previous_slide = slide.channel_id.slide_ids[slide_index-1] if slide_index > 0 else None + next_slide = slide.channel_id.slide_ids[slide_index+1] if slide_index < len(channel_slides_ids) - 1 else None + values = { + # slide 'slide': slide, 'most_viewed_slides': most_viewed_slides, 'related_slides': related_slides, + 'previous_slide': previous_slide, + 'next_slide': next_slide, + 'uncategorized_slides': uncategorized_slides, + # user 'user': request.env.user, + 'user_progress': self._get_user_progress(slide.channel_id)['user_progress'], 'is_public_user': request.website.is_public_user(), + # rating and comments 'comments': slide.website_message_ids or [], - 'user_progress': {} } - if slide.channel_id.channel_type == "training": - channel_slides_ids = slide.channel_id.slide_ids.ids - slide_index = channel_slides_ids.index(slide.id) - previous_slide = slide.channel_id.slide_ids[slide_index-1] if slide_index > 0 else None - next_slide = slide.channel_id.slide_ids[slide_index+1] if slide_index < len(channel_slides_ids) - 1 else None + + # allow rating and comments + if slide.channel_id.allow_comment: values.update({ - 'previous_slide': slug(previous_slide) if previous_slide else "", - 'next_slide': slug(next_slide) if next_slide else "" + 'message_post_hash': slide._generate_signed_token(request.env.user.partner_id.id), + 'message_post_pid': request.env.user.partner_id.id, }) + return values def _get_quiz_points(self, slide, attempt_count): @@ -494,21 +510,12 @@ class WebsiteSlides(WebsiteProfile): def slide_view(self, slide, **kwargs): if not slide.channel_id.can_access_from_current_website(): raise werkzeug.exceptions.NotFound() + self._set_viewed_slide(slide) - self._set_viewed_slide(slide) values = self._get_slide_detail(slide) - # allow rating and comments - if slide.channel_id.allow_comment: - values.update({ - 'message_post_hash': slide._generate_signed_token(request.env.user.partner_id.id), - 'message_post_pid': request.env.user.partner_id.id, - }) - self._set_viewed_slide(slide) - if slide.channel_id.channel_type == "training": - values.update(self._get_user_progress(slide.channel_id)) - values['uncategorized_slides'] = slide.channel_id.slide_ids.filtered(lambda slide: not slide.category_id) - if 'fullscreen' in kwargs: - return request.render("website_slides.slide_fullscreen", values) + + if 'fullscreen' in kwargs: + return request.render("website_slides.slide_fullscreen", values) return request.render("website_slides.slide_detail_view", values) @http.route('''/slides/slide//pdf_content''', diff --git a/addons/website_slides/views/website_slides_templates_lesson.xml b/addons/website_slides/views/website_slides_templates_lesson.xml index 98f7577b848..c59661e8fd1 100644 --- a/addons/website_slides/views/website_slides_templates_lesson.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -55,13 +55,13 @@ From 3bdccc08677ac6a3a966dc737c4c53baafa93a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 6 Mar 2019 10:48:33 +0000 Subject: [PATCH 4/9] [FIX] website_slides: latest courses should display all my courses Correctly fetch courses the current user is a member of, not those he already finished at least a lesson. Commit linked to task ID 1941250 and PR #31512. --- addons/website_slides/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index ca01baea917..1f3e78c4a16 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -192,7 +192,7 @@ class WebsiteSlides(WebsiteProfile): domain = request.website.website_domain() channels_all = request.env['slide.channel'].search(domain) if not request.env.user._is_public(): - channels_my = channels_all.filtered(lambda channel: channel.completion > 0).sorted('completion', reverse=True)[:3] + channels_my = channels_all.filtered(lambda channel: channel.is_member).sorted('completion', reverse=True)[:3] else: channels_my = request.env['slide.channel'] channels_popular = channels_all.sorted('total_votes', reverse=True)[:3] From 9e7c5537d243335b6adbdb2cf5fcb5423c203a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 6 Mar 2019 13:48:22 +0000 Subject: [PATCH 5/9] [FIX] website_slides: fix set viewed slide Currently a slide that can be previewed is never set as completed. Correct condition to not update the hard slide-partner relationship is: * either current user is public; * either current slide is not published (happens when a publisher sees still unpublished lessons); * either current user is not member of slide channel (happens when seeing a free preview slide without being channel member); Commit linked to task ID 1941250 and PR #31512. --- addons/website_slides/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 1f3e78c4a16..087ed6919fa 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -52,7 +52,7 @@ class WebsiteSlides(WebsiteProfile): return {'slide': slide} def _set_viewed_slide(self, slide): - if request.env.user._is_public() or slide.is_preview or not slide.channel_id.is_member: + if request.env.user._is_public() or not slide.website_published or not slide.channel_id.is_member: viewed_slides = request.session.setdefault('viewed_slides', list()) if slide.id not in viewed_slides: slide.sudo().public_views += 1 From 31d9bbd904d58661fe26854f28e572b0e1364061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 5 Mar 2019 11:52:51 +0000 Subject: [PATCH 6/9] [FIX] website_slides: add gray background to lesson not fullscreen display Simple fix to already have the standard gray background. Future commits will improve display of not fullscreen lessons but this fix was necessary for incoming work. Commit linked to task ID 1941250 and PR #31512. --- addons/website_slides/views/website_slides_templates_lesson.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/website_slides/views/website_slides_templates_lesson.xml b/addons/website_slides/views/website_slides_templates_lesson.xml index c59661e8fd1..e6df3294289 100644 --- a/addons/website_slides/views/website_slides_templates_lesson.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -8,6 +8,7 @@ +
@@ -416,6 +417,7 @@
+
From c7cceaef793052a98c159822a75ba0abf76d57a4 Mon Sep 17 00:00:00 2001 From: David Beguin Date: Mon, 4 Mar 2019 15:08:28 +0000 Subject: [PATCH 7/9] [FIX] website_profile : hide badge if not website_published on user's profile page Badges that should be displayed on user's profile page must be website published. Badges that are website_published are typically forum badges or others that will be configured for eLearning. Task ID : 1941250 PR #31512 --- addons/website_profile/views/website_profile.xml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/addons/website_profile/views/website_profile.xml b/addons/website_profile/views/website_profile.xml index 8b088740ca6..602258ee30f 100644 --- a/addons/website_profile/views/website_profile.xml +++ b/addons/website_profile/views/website_profile.xml @@ -254,16 +254,18 @@ From 6aedd56c40ed2044dde859145212b5b0a9d02527 Mon Sep 17 00:00:00 2001 From: David Beguin Date: Wed, 6 Mar 2019 10:55:15 +0000 Subject: [PATCH 9/9] [FIX] website_slides_forum : fix elearning navbar style in forum Since design refactoring from af41382fa182fde43f8a52cb33171071f42dcd20, eLearning navbar style was not displayed correctly. This commit fixes this by applying same design rules as user profile page navbar. Task ID : 1941250 PR #31512 --- addons/website_forum/static/src/scss/website_forum.scss | 5 +++++ .../views/website_slides_forum_templates.xml | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/website_forum/static/src/scss/website_forum.scss b/addons/website_forum/static/src/scss/website_forum.scss index 8d645e26030..391adf9d792 100644 --- a/addons/website_forum/static/src/scss/website_forum.scss +++ b/addons/website_forum/static/src/scss/website_forum.scss @@ -218,3 +218,8 @@ img.o_forum_avatar_big { min-height: 75px; } } + +.o_wforum_elearning_navtabs_container { + height: $owprofile-tabs-height; + background-color: #66445e; +} diff --git a/addons/website_slides_forum/views/website_slides_forum_templates.xml b/addons/website_slides_forum/views/website_slides_forum_templates.xml index 2c47c9e759c..b0342ec4077 100644 --- a/addons/website_slides_forum/views/website_slides_forum_templates.xml +++ b/addons/website_slides_forum/views/website_slides_forum_templates.xml @@ -3,9 +3,9 @@