Master forum pimp and pump promenade loma
website_* * = forum, profile, slides, slides_forum, slides_survey Purpose ======= Make it possible for users to have an overview and search in all forums. This includes searching for posts of other users, and their own upvoted posts, much like /slides/all. Give users a better experience when browsing website profiles looking for courses, certifications, forum questions, ... Specifications ============= Add route for `/forum/all` change templates in `website_forum` to show posts even if `forum` is not specified to shows results and search in all forums Add search bars for Questions, Answers and Upvotes, small UI changes here and there. Task-2676848 Co-authored by: Fabio Barbero <faba@odoo.com> closes odoo/odoo#129123 Related: odoo/enterprise#47207 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -73,31 +73,39 @@ class WebsiteForum(WebsiteProfile):
|
||||
if not qs or qs.lower() in loc:
|
||||
yield {'loc': loc}
|
||||
|
||||
def _get_forum_port_search_options(self, forum=None, tag=None, filters=None, my=None, **post):
|
||||
def _get_forum_post_search_options(self, forum=None, tag=None, filters=None, my=None, create_uid=False, include_answers=False, **post):
|
||||
return {
|
||||
'allowFuzzy': not post.get('noFuzzy'),
|
||||
'create_uid': create_uid,
|
||||
'displayDescription': False,
|
||||
'displayDetail': False,
|
||||
'displayExtraDetail': False,
|
||||
'displayExtraLink': False,
|
||||
'displayImage': False,
|
||||
'allowFuzzy': not post.get('noFuzzy'),
|
||||
'forum': str(forum.id) if forum else None,
|
||||
'tag': str(tag.id) if tag else None,
|
||||
'filters': filters,
|
||||
'forum': str(forum.id) if forum else None,
|
||||
'include_answers': include_answers,
|
||||
'my': my,
|
||||
'tag': str(tag.id) if tag else None,
|
||||
}
|
||||
|
||||
@http.route(['/forum/<model("forum.forum"):forum>',
|
||||
@http.route(['/forum/all',
|
||||
'/forum/all/page/<int:page>',
|
||||
'/forum/<model("forum.forum"):forum>',
|
||||
'/forum/<model("forum.forum"):forum>/page/<int:page>',
|
||||
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag"):tag>/questions''',
|
||||
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag"):tag>/questions/page/<int:page>''',
|
||||
], type='http', auth="public", website=True, sitemap=sitemap_forum)
|
||||
def questions(self, forum, tag=None, page=1, filters='all', my=None, sorting=None, search='', **post):
|
||||
def questions(self, forum=None, tag=None, page=1, filters='all', my=None, sorting=None, search='', create_uid=False, include_answers=False, **post):
|
||||
Post = request.env['forum.post']
|
||||
|
||||
author = request.env['res.users'].browse(int(create_uid))
|
||||
|
||||
if author == request.env.user:
|
||||
my = 'mine'
|
||||
if sorting:
|
||||
# check that sorting is valid
|
||||
# retro-compatibily for V8 and google links
|
||||
# retro-compatibility for V8 and google links
|
||||
try:
|
||||
sorting = werkzeug.urls.url_unquote_plus(sorting)
|
||||
Post._generate_order_by(sorting, None)
|
||||
@@ -105,13 +113,16 @@ class WebsiteForum(WebsiteProfile):
|
||||
sorting = False
|
||||
|
||||
if not sorting:
|
||||
sorting = forum.default_order
|
||||
sorting = forum.default_order if forum else 'last_activity_date desc'
|
||||
|
||||
options = self._get_forum_port_search_options(
|
||||
options = self._get_forum_post_search_options(
|
||||
forum=forum,
|
||||
tag=tag,
|
||||
filters=filters,
|
||||
my=my,
|
||||
create_uid=author.id,
|
||||
include_answers=include_answers,
|
||||
my_profile=request.env.user == author,
|
||||
**post
|
||||
)
|
||||
question_count, details, fuzzy_search_term = request.website._search_with_fuzzy(
|
||||
@@ -119,7 +130,11 @@ class WebsiteForum(WebsiteProfile):
|
||||
question_ids = details[0].get('results', Post)
|
||||
question_ids = question_ids[(page - 1) * self._post_per_page:page * self._post_per_page]
|
||||
|
||||
url = f"/forum/{slug(forum)}{f'/tag/{slug(tag)}/questions' if tag else ''}"
|
||||
if not forum:
|
||||
url = '/forum/all'
|
||||
else:
|
||||
url = f"/forum/{slug(forum)}{f'/tag/{slug(tag)}/questions' if tag else ''}"
|
||||
|
||||
url_args = {'sorting': sorting}
|
||||
|
||||
for name, value in zip(['filters', 'search', 'my'], [filters, search, my]):
|
||||
@@ -132,7 +147,7 @@ class WebsiteForum(WebsiteProfile):
|
||||
|
||||
values = self._prepare_user_values(forum=forum, searches=post)
|
||||
values.update({
|
||||
'main_object': tag or forum,
|
||||
'author': author,
|
||||
'edit_in_backend': True,
|
||||
'question_ids': question_ids,
|
||||
'question_count': question_count,
|
||||
@@ -145,6 +160,10 @@ class WebsiteForum(WebsiteProfile):
|
||||
'search': fuzzy_search_term or search,
|
||||
'original_search': fuzzy_search_term and search,
|
||||
})
|
||||
|
||||
if forum or tag:
|
||||
values['main_object'] = tag or forum
|
||||
|
||||
return request.render("website_forum.forum_index", values)
|
||||
|
||||
@http.route(['''/forum/<model("forum.forum"):forum>/faq'''], type='http', auth="public", website=True, sitemap=True)
|
||||
@@ -602,9 +621,10 @@ class WebsiteForum(WebsiteProfile):
|
||||
# Profile
|
||||
# -----------------------------------
|
||||
|
||||
@http.route(['/forum/<model("forum.forum"):forum>/user/<int:user_id>'], type='http', auth="public", website=True)
|
||||
def view_user_forum_profile(self, forum, user_id, forum_origin='/forum', **post):
|
||||
return request.redirect(f'/profile/user/{user_id}?forum_id={forum.id}&forum_origin={forum_origin}')
|
||||
@http.route(['/forum/user/<int:user_id>'], type='http', auth="public", website=True)
|
||||
def view_user_forum_profile(self, user_id, forum_id='', forum_origin='/forum', **post):
|
||||
forum_origin_query = f'?forum_origin={forum_origin}&forum_id={forum_id}' if forum_id else ''
|
||||
return request.redirect(f'/profile/user/{user_id}{forum_origin_query}')
|
||||
|
||||
def _prepare_user_profile_values(self, user, **post):
|
||||
values = super(WebsiteForum, self)._prepare_user_profile_values(user, **post)
|
||||
|
||||
@@ -9,6 +9,7 @@ from datetime import datetime
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.addons.http_routing.models.ir_http import slug, unslug
|
||||
from odoo.exceptions import UserError, ValidationError, AccessError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import sql
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -804,30 +805,36 @@ class Post(models.Model):
|
||||
}
|
||||
|
||||
domain = website.website_domain()
|
||||
domain += [('parent_id', '=', False), ('state', '=', 'active'), ('can_view', '=', True)]
|
||||
domain = expression.AND([domain, [('state', '=', 'active'), ('can_view', '=', True)]])
|
||||
include_answers = options.get('include_answers', False)
|
||||
if not include_answers:
|
||||
domain = expression.AND([domain, [('parent_id', '=', False)]])
|
||||
forum = options.get('forum')
|
||||
if forum:
|
||||
domain += [('forum_id', '=', unslug(forum)[1])]
|
||||
domain = expression.AND([domain, [('forum_id', '=', unslug(forum)[1])]])
|
||||
tags = options.get('tag')
|
||||
if tags:
|
||||
domain += [('tag_ids', 'in', [unslug(tag)[1] for tag in tags.split(',')])]
|
||||
domain = expression.AND([domain, [('tag_ids', 'in', [unslug(tag)[1] for tag in tags.split(',')])]])
|
||||
filters = options.get('filters')
|
||||
if filters == 'unanswered':
|
||||
domain += [('child_ids', '=', False)]
|
||||
domain = expression.AND([domain, [('child_ids', '=', False)]])
|
||||
elif filters == 'solved':
|
||||
domain += [('has_validated_answer', '=', True)]
|
||||
domain = expression.AND([domain, [('has_validated_answer', '=', True)]])
|
||||
elif filters == 'unsolved':
|
||||
domain += [('has_validated_answer', '=', False)]
|
||||
domain = expression.AND([domain, [('has_validated_answer', '=', False)]])
|
||||
user = self.env.user
|
||||
my = options.get('my')
|
||||
if my == 'mine':
|
||||
domain += [('create_uid', '=', user.id)]
|
||||
elif my == 'followed':
|
||||
domain += [('message_partner_ids', '=', user.partner_id.id)]
|
||||
create_uid = user.id if my == 'mine' else options.get('create_uid')
|
||||
if create_uid:
|
||||
domain = expression.AND([domain, [('create_uid', '=', create_uid)]])
|
||||
if my == 'followed':
|
||||
domain = expression.AND([domain, [('message_partner_ids', '=', user.partner_id.id)]])
|
||||
elif my == 'tagged':
|
||||
domain += [('tag_ids.message_partner_ids', '=', user.partner_id.id)]
|
||||
domain = expression.AND([domain, [('tag_ids.message_partner_ids', '=', user.partner_id.id)]])
|
||||
elif my == 'favourites':
|
||||
domain += [('favourite_ids', '=', user.id)]
|
||||
domain = expression.AND([domain, [('favourite_ids', '=', user.id)]])
|
||||
elif my == 'upvoted':
|
||||
domain = expression.AND([domain, [('vote_ids.user_id', '=', user.id)]])
|
||||
|
||||
# 'sorting' from the form's "Order by" overrides order during auto-completion
|
||||
order = options.get('sorting', order)
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
<th class="o_wforum_table_title"></th>
|
||||
<th class="o_wforum_table_posters"></th>
|
||||
<th class="o_wforum_table_replies small fw-normal text-center">
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', sorting='child_count asc' if sorting == 'child_count desc' else 'child_count desc') }">
|
||||
Replies <i t-attf-class="fa fa-caret-#{ 'down' if sorting == 'child_count desc' else 'up' } #{ 'd-none ' if not sorting.startswith('child_count') else '' }"></i>
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', 'my', 'create_uid', sorting='child_count asc' if sorting == 'child_count desc' else 'child_count desc') }">
|
||||
Replies <i t-attf-class="fa fa-caret-#{ 'down' if sorting == 'child_count desc' else 'up' } #{ not sorting.startswith('child_count') and 'd-none ' }"></i>
|
||||
</a>
|
||||
</th>
|
||||
<th class="o_wforum_table_views small fw-normal text-center">
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', sorting='views asc' if sorting == 'views desc' else 'views desc') }">
|
||||
Views <i t-attf-class="fa fa-caret-#{'down' if sorting == 'views desc' else 'up'} #{ 'd-none ' if not sorting.startswith('views') else '' }"></i>
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', 'my', 'create_uid', sorting='views asc' if sorting == 'views desc' else 'views desc') }">
|
||||
Views <i t-attf-class="fa fa-caret-#{'down' if sorting == 'views desc' else 'up'} #{ not sorting.startswith('views') and 'd-none ' }"></i>
|
||||
</a>
|
||||
</th>
|
||||
<th class="o_wforum_table_activity small fw-normal text-center">
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', sorting='last_activity_date asc' if sorting == 'last_activity_date desc' else 'last_activity_date desc') }">
|
||||
<a class="text-muted" t-attf-href="?#{ keep_query('search', 'filters', 'my', 'create_uid', sorting='last_activity_date asc' if sorting == 'last_activity_date desc' else 'last_activity_date desc') }">
|
||||
Activity <i t-attf-class="fa fa-caret-#{ 'down' if sorting == 'last_activity_date desc' else 'up'} #{ 'd-none ' if not sorting.startswith('last_activity') else '' }"></i>
|
||||
</a>
|
||||
</th>
|
||||
@@ -45,7 +45,8 @@
|
||||
</table>
|
||||
<t t-if="question_count == 0 or original_search" t-call="website_forum.no_results_message">
|
||||
<t t-set="record_name_plural">posts</t>
|
||||
<t t-set="go_back_url" t-valuef="/forum/#{ slug(forum) }/"/>
|
||||
<t t-set="_forum_slug" t-value="slug(forum) if forum else 'all'"/>
|
||||
<t t-set="go_back_url" t-valuef="/forum/#{_forum_slug}/"/>
|
||||
</t>
|
||||
<t t-call="website.pager"/>
|
||||
</t>
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
<!-- PAGE INDEX -->
|
||||
<!-- ============================================================ -->
|
||||
<template id="forum_model_nav">
|
||||
<t t-set="_forum_slug" t-value="slug(forum) if forum else 'all'"/>
|
||||
<t t-set="_all_forums">All forums</t>
|
||||
<t t-set="_forum_name" t-value="forum.name if forum else _all_forums"/>
|
||||
<!-- allows to be overridden such as in website_slides_forum -->
|
||||
<t t-set="breadcrumb_kind" t-valuef="base"/>
|
||||
<nav id="o_wforum_nav" t-attf-class="navbar d-flex align-items-baseline gap-2 #{ 'mw-xl-75 mw-xxl-100' if _page_name == 'single_question' else '' } px-0" aria-label="breadcrumb">
|
||||
@@ -25,8 +28,8 @@
|
||||
<div class="flex-grow-1">
|
||||
<div class="o_wforum_breadcrumb_root_single row g-0">
|
||||
<div t-if="breadcrumb_kind == 'base'" class="col-10">
|
||||
<a class="btn btn-lg btn-link px-0 pb-2" t-attf-href="/forum/#{ slug(forum) }">
|
||||
<i class="d-inline-block oi oi-chevron-left me-1 small lh-50"/><t t-out="forum.name"/>
|
||||
<a class="btn btn-lg btn-link px-0 pb-2" t-attf-href="/forum/#{ _forum_slug }">
|
||||
<i class="d-inline-block oi oi-chevron-left me-1 small lh-50"/><t t-out="_forum_name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-lg-none col-2 text-end">
|
||||
@@ -67,7 +70,7 @@
|
||||
<t t-set="target" t-value="post.parent_id if is_answer else post"/>
|
||||
<div class="o_wforum_breadcrumb_root_list_or_edit d-flex">
|
||||
<div t-if="breadcrumb_kind=='base'" class="col-10 col-lg flex-grow-1">
|
||||
<h5 t-if="not is_edit" class="fw-bold mb-0" t-out="forum.name"/>
|
||||
<h5 t-if="not is_edit" class="fw-bold mb-0" t-out="_forum_name"/>
|
||||
<h5 t-elif="not is_answer" class="fw-bold mb-0">Edit Question</h5>
|
||||
<h5 t-else="is_answer" class="fw-bold mb-0">Edit Answer</h5>
|
||||
</div>
|
||||
@@ -75,7 +78,7 @@
|
||||
</t>
|
||||
<ol t-else="" class="breadcrumb col-10 col-lg flex-grow-1 mb-0 p-0">
|
||||
<li class="o_wforum_breadcrumb_root breadcrumb-item text-nowrap">
|
||||
<h5 class="mb-0"><a t-attf-href="/forum/#{ slug(forum) }" t-out="forum.name"/></h5>
|
||||
<h5 class="mb-0"><a t-attf-href="/forum/#{ _forum_slug }" t-out="_forum_name"/></h5>
|
||||
</li>
|
||||
<li t-if="queue_type" class="breadcrumb-item text-nowrap d-none d-lg-flex">
|
||||
<h5 class="mb-0">Moderation</h5>
|
||||
@@ -93,7 +96,7 @@
|
||||
<div t-attf-class="d-flex justify-content-lg-end gap-2 flex-grow-1 w-100 w-lg-auto #{'mw-xl-75' if search else 'mw-xl-50'}">
|
||||
<span t-if="tag and not tags" class="btn btn-light rounded ps-2">
|
||||
<span t-if="tag"><i class="fa fa-tag me-1 text-muted"/><t t-out="tag.name"></t></span>
|
||||
<a t-attf-href="#{ url_for('/forum') }/#{ slug(forum) }?#{ keep_query('search', 'sorting', 'my') }"
|
||||
<a t-attf-href="#{ url_for('/forum') }/#{ _forum_slug }?#{ keep_query('search', 'sorting', 'my', 'create_uid') }"
|
||||
class="p-1 text-decoration-none text-muted"><i class="oi oi-close d-inline-block"/></a>
|
||||
</span>
|
||||
<span t-if="search" class="btn btn-light rounded ps-2">
|
||||
@@ -119,7 +122,7 @@
|
||||
</t>
|
||||
</a>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a t-attf-href="?#{ keep_query('search', 'sorting', filters='all') }"
|
||||
<a t-attf-href="?#{ keep_query('search', 'sorting', 'create_uid', filters='all') }"
|
||||
class="dropdown-item">
|
||||
All
|
||||
</a>
|
||||
@@ -129,7 +132,7 @@
|
||||
t-attf-href="?#{ keep_query('search', 'sorting', 'my', filters='followed') }"
|
||||
class="dropdown-item">Followed Tags
|
||||
</a>
|
||||
<t t-if="forum.can_moderate">
|
||||
<t t-if="forum and forum.can_moderate">
|
||||
<a t-attf-href="?#{ keep_query('search', 'sorting', 'my', filters='unused') }"
|
||||
class="dropdown-item">Unused Tags
|
||||
</a>
|
||||
@@ -139,7 +142,7 @@
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="forum.mode == 'questions'">
|
||||
<t t-if="not forum or (forum and forum.mode == 'questions')">
|
||||
<a t-attf-href="?#{ keep_query('search', 'sorting', 'my', filters='solved') }"
|
||||
class="dropdown-item">Solved
|
||||
</a>
|
||||
@@ -157,11 +160,11 @@
|
||||
<t t-if="question_count or tags" t-call="website.website_search_box_input">
|
||||
<t t-if="_page_name == 'tags'">
|
||||
<t t-set="search_type" t-value="'forum_tags_only'"/>
|
||||
<t t-set="action" t-valuef="/forum/#{ slug(forum) }/tag"/>
|
||||
<t t-set="action" t-valuef="'/forum/%s/tag' % (_forum_slug)"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-set="search_type" t-value="'forums'"/>
|
||||
<t t-set="action" t-value="'/forum/' + slug(forum)"/>
|
||||
<t t-set="action" t-value="'/forum/%s' % (_forum_slug)"/>
|
||||
</t>
|
||||
<t t-set="display_description" t-valuef="true"/>
|
||||
<t t-set="display_detail" t-valuef="true"/>
|
||||
@@ -181,7 +184,7 @@
|
||||
t-att-data-bs-content="popover_content">
|
||||
<a class="o_wforum_ask_btn disabled btn btn-primary mb-3 mb-md-0" t-attf-href="/forum/#{ slug(forum) }/ask">New Post</a>
|
||||
</div>
|
||||
<a t-elif="uid" role="button" type="button" t-attf-class="o_wforum_ask_btn btn btn-primary #{ 'karma_required' if user.karma < forum.karma_ask else '' }"
|
||||
<a t-elif="uid and forum" role="button" type="button" t-attf-class="o_wforum_ask_btn btn btn-primary #{ 'karma_required' if user.karma < forum.karma_ask else '' }"
|
||||
t-att-data-karma="forum.karma_ask" t-attf-href="/forum/#{slug(forum)}/ask">New Post</a>
|
||||
</t>
|
||||
<button t-if="website_forum_action and not queue_type == 'close' and posts_ids" type="button" class="o_wforum_btn_filter_tool btn btn-secondary"
|
||||
@@ -194,32 +197,35 @@
|
||||
</template>
|
||||
|
||||
<template id="header" name="Forum Index">
|
||||
<t t-if="forum.active" t-call="website_forum.layout">
|
||||
<div class="oe_structure" id="oe_structure_website_forum_header_1"/>
|
||||
<div id="wrap" t-attf-class="o_wforum_wrapper position-relative container d-flex d-xl-grid px-lg-0 #{ 'h-100' if forum_welcome_message else ''} #{website_forum_action}">
|
||||
<t t-set="_forum_path" t-value="url_for('/forum') + '/' + slug(forum)"/>
|
||||
<t t-call="website_forum.user_sidebar"/>
|
||||
<t t-call="website_forum.user_sidebar_mobile"/>
|
||||
<div class="o_wforum_content_wrapper w-100 w-xl-auto px-lg-3">
|
||||
<div class="o_wprofile_email_validation_container row g-0 justify-content-center mb-3 mb-lg-5 pt-2 pt-lg-3">
|
||||
<t t-call="website_profile.email_validation_banner">
|
||||
<t t-set="redirect_url" t-value="'/forum/%s' % forum.id"/>
|
||||
<t t-set="additional_validation_email_message"> and join this Forum</t>
|
||||
<t t-set="additional_validated_email_message"> You may now participate in our forums.</t>
|
||||
</t>
|
||||
<t t-call="website_forum.forum_model_nav"/>
|
||||
<t t-out="0"/>
|
||||
<t t-call="website_forum.layout">
|
||||
<t t-if="forum and not forum.active">
|
||||
<t t-set="head">
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
</t>
|
||||
<div class="text-center text-muted">
|
||||
<p class="css_editable_hidden"><h2>This forum has been archived.</h2></p>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="oe_structure" id="oe_structure_website_forum_header_1"/>
|
||||
<div id="wrap" t-attf-class="o_wforum_wrapper position-relative container d-flex d-xl-grid px-lg-0 #{ 'h-100' if forum_welcome_message else ''} #{website_forum_action}">
|
||||
<t t-set="_forum_slug" t-value="slug(forum) if forum else 'all'"/>
|
||||
<t t-set="_forum_path" t-value="url_for('/forum') + '/' + _forum_slug"/>
|
||||
<t t-call="website_forum.user_sidebar"/>
|
||||
<t t-call="website_forum.user_sidebar_mobile"/>
|
||||
<div class="o_wforum_content_wrapper w-100 w-xl-auto px-lg-3">
|
||||
<div class="o_wprofile_email_validation_container row g-0 justify-content-center mb-3 mb-lg-5 pt-2 pt-lg-3">
|
||||
<t t-call="website_profile.email_validation_banner">
|
||||
<t t-set="redirect_url" t-value="'/forum/%s' % forum.id if forum else '/forum/all/'"/>
|
||||
<t t-set="additional_validation_email_message"> and join this Forum</t>
|
||||
<t t-set="additional_validated_email_message"> You may now participate in our forums.</t>
|
||||
</t>
|
||||
<t t-call="website_forum.forum_model_nav"/>
|
||||
<t t-out="0"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="" t-call="website_forum.layout">
|
||||
<t t-set="head">
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
</t>
|
||||
<div class="text-center text-muted">
|
||||
<p class="css_editable_hidden"><h2>This forum has been archived.</h2></p>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -230,7 +236,7 @@
|
||||
<t t-call="website_forum.user_sidebar_header"/>
|
||||
<t t-call="website_forum.user_sidebar_body"/>
|
||||
</div>
|
||||
<div class="o_wforum_sidebar_footer mt-3 px-3 pb-2 text-center">
|
||||
<div t-if="forum" class="o_wforum_sidebar_footer mt-3 px-3 pb-2 text-center">
|
||||
<a class="btn btn-sm btn-link" t-attf-href="/forum/#{slug(forum)}/faq">
|
||||
<i class="fa fa-info-circle fa-fw"/> About this forum
|
||||
</a>
|
||||
@@ -245,7 +251,7 @@
|
||||
<div class="offcanvas-header align-items-start px-0" t-call="website_forum.user_sidebar_header"/>
|
||||
<div class="offcanvas-body d-flex flex-column ps-0 py-0">
|
||||
<t t-call="website_forum.user_sidebar_body"/>
|
||||
<div class="mb-2 d-flex justify-content-center align-items-end flex-grow-1">
|
||||
<div t-if="forum" class="mb-2 d-flex justify-content-center align-items-end flex-grow-1">
|
||||
<a class="btn btn-sm btn-link" t-att-href="_forum_path + '/faq'">
|
||||
<i class="fa fa-info-circle fa-fw"/> About this forum
|
||||
</a>
|
||||
@@ -256,7 +262,7 @@
|
||||
|
||||
<!-- User sidebar elements -->
|
||||
<template id="user_sidebar_header">
|
||||
<t t-set="_location" t-value="('/tag/' + slug(tag) + '/questions?') if tag else '?' "/>
|
||||
<t t-set="_location" t-value="( ('/tag/' + slug(tag) + '/questions?') if tag else '?' )"/>
|
||||
|
||||
<div t-if="not uid" class="o_wforum_sidebar_section mt-4 text-center">
|
||||
<div class="alert alert-info mb-2"><span>You need to be registered to interact with the community.</span>
|
||||
@@ -264,7 +270,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="uid" class="o_wforum_sidebar_section mt-4 mb-2">
|
||||
<a t-attf-href="#{ _forum_path }/user/#{ uid }?forum_origin=#{ request.httprequest.path }"
|
||||
<a t-attf-href="/forum/user/#{ uid }?forum_id=#{ forum.id if forum else '' }&forum_origin=#{ request.httprequest.path }"
|
||||
class="btn w-100 py-1 text-start d-flex align-items-center" data-bs-toggle="tooltip" data-trigger="hover"
|
||||
title="My profile">
|
||||
<img class="o_wforum_avatar rounded-circle" t-att-src="request.website.image_url(user, 'avatar_128', '60x60')" alt="Avatar"/>
|
||||
@@ -304,22 +310,22 @@
|
||||
<i class="fa fa-shield fa-fw opacity-50"/> Badges
|
||||
</a>
|
||||
</div>
|
||||
<div t-if="user.karma >= forum.karma_moderate" class="o_wforum_sidebar_section pt-3">
|
||||
<div t-if="forum and user.karma>=forum.karma_moderate" class="o_wforum_sidebar_section pt-3">
|
||||
<!-- Moderation Tools -->
|
||||
<div class="px-3 pb-1 fw-bold">Moderation tools</div>
|
||||
<a t-attf-class="nav-link my-1 py-1 #{ 'bg-primary-light text-primary disabled' if queue_type == 'validation' else 'text-reset'}" t-attf-href="/forum/#{slug(forum)}/validation_queue">
|
||||
<a t-attf-class="nav-link my-1 py-1 #{ 'bg-primary-light text-primary disabled' if queue_type == 'validation' else 'text-reset'}" t-attf-href="/forum/#{_forum_slug}/validation_queue">
|
||||
<i t-attf-class="fa fa-check-square-o fa-fw #{ 'opacity-50' if queue_type != 'validation' else ''}"/> To Validate
|
||||
<span id="count_posts_queue_validation" t-attf-class="badge #{ 'text-bg-warning' if forum.count_posts_waiting_validation > 0 else 'd-none'}" t-out="forum.count_posts_waiting_validation"/>
|
||||
</a>
|
||||
<a t-attf-class="nav-link my-1 py-1 #{'bg-primary-light text-primary disabled' if queue_type == 'offensive' or queue_type == 'flagged' else 'text-reset'}" t-attf-href="/forum/#{slug(forum)}/flagged_queue">
|
||||
<a t-attf-class="nav-link my-1 py-1 #{'bg-primary-light text-primary disabled' if queue_type == 'offensive' or queue_type == 'flagged' else 'text-reset'}" t-attf-href="/forum/#{_forum_slug}/flagged_queue">
|
||||
<i t-attf-class="fa fa-flag fa-fw #{ 'opacity-50' if queue_type != 'flagged' else ''}"/> Flagged
|
||||
<span id="count_posts_queue_flagged" t-attf-class="badge #{ 'text-bg-danger' if forum.count_flagged_posts > 0 else 'd-none'}" t-out="forum.count_flagged_posts"/>
|
||||
</a>
|
||||
<a t-attf-class="nav-link my-1 py-1 #{ 'bg-primary-light text-primary disabled' if queue_type == 'close' else 'text-reset'}" t-attf-href="/forum/#{slug(forum)}/closed_posts">
|
||||
<a t-attf-class="nav-link my-1 py-1 #{ 'bg-primary-light text-primary disabled' if queue_type == 'close' else 'text-reset'}" t-attf-href="/forum/#{_forum_slug}/closed_posts">
|
||||
<i t-attf-class="fa fa-window-close fa-fw #{ 'opacity-50' if queue_type != 'close' else '' }"/> Closed
|
||||
</a>
|
||||
</div>
|
||||
<div t-if="forum.tag_most_used_ids" class="o_wforum_sidebar_section pt-3">
|
||||
<div t-if="forum and forum.tag_most_used_ids" class="o_wforum_sidebar_section pt-3">
|
||||
<div class="d-flex align-items-center px-3 pb-1 fw-bold">Tags
|
||||
<a class="ms-auto px-0 fw-normal" t-att-href="_forum_path + '/tag'">
|
||||
<small>View all</small>
|
||||
@@ -336,7 +342,7 @@
|
||||
|
||||
<template id="header_welcome_message" inherit_id="website_forum.header" name="Forum Welcome Message (oe_structure_forum_top)">
|
||||
<xpath expr="//*[hasclass('oe_structure')][@id='oe_structure_website_forum_header_1']" position="replace">
|
||||
<div class="oe_structure oe_empty" id="oe_structure_website_forum_header_1">
|
||||
<div t-if="forum" class="oe_structure oe_empty" id="oe_structure_website_forum_header_1">
|
||||
<section t-if="editable or (is_public_user and not forum_welcome_message)" t-attf-class="s_cover parallax s_parallax_is_fixed bg-black-50 pt48 pb48 #{'css_non_editable_mode_hidden' if editable else 'forum_intro'}" data-scroll-background-ratio="1" data-snippet="s_cover">
|
||||
<span t-if="forum.image_1920" class="s_parallax_bg oe_img_bg" t-attf-style="background-image: url('#{request.website.image_url(forum, 'image_1920')}'); background-position: center;"/>
|
||||
<div t-if="forum.image_1920" class="o_we_bg_filter bg-black-50"/>
|
||||
@@ -377,14 +383,14 @@
|
||||
</t>.
|
||||
</span>
|
||||
<span t-if="original_search">Showing results for <em class="fw-bold" t-out="search"/> instead.</span>
|
||||
<div t-if="question_count == 0 and forum.total_posts != 0" class="mt-3 text-start">
|
||||
<div t-if="question_count == 0 and (not forum or forum.total_posts != 0)" class="mt-3 text-start">
|
||||
<p><i class="fa fa-check fa-fw me-1"/>Check your spelling and try again.</p>
|
||||
<p><i class="fa fa-check fa-fw me-1"/>Try searching for one or two words.</p>
|
||||
<p><i class="fa fa-check fa-fw me-1"/>Be less specific in your wording for a wider search result.</p>
|
||||
</div>
|
||||
<span t-elif="forum.total_posts == 0">Actually, there are no posts in this forum yet.</span>
|
||||
<span t-elif="forum and forum.total_posts == 0">Because there are no posts in this forum yet.</span>
|
||||
<div class="mt-3">
|
||||
<a t-if="uid and forum.total_posts == 0" role="button" type="button" class="o_forum_ask_btn btn btn-primary ms-2" t-attf-href="/forum/#{slug(forum)}/ask">Start by creating a post</a>
|
||||
<a t-if="uid and forum and forum.total_posts == 0" role="button" type="button" class="o_forum_ask_btn btn btn-primary ms-2" t-attf-href="/forum/#{_forum_slug}/ask">Start by creating a post</a>
|
||||
<a t-else="" role="button" type="button" class="btn btn-primary mt-2" t-att-href="go_back_url">Go back to the list of <t t-out="record_name_plural"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<a t-attf-href="/forum/#{slug(question.forum_id)}/#{slug(question)}#{ ('/#answer-%s' % answer.id) if answer else '' }"
|
||||
t-attf-title="Read: #{question.name}"
|
||||
t-attf-class="stretched-link text-body #{_link_classes}">
|
||||
<span t-out="question.name"/>
|
||||
<span t-out="question.name" t-if="question.name"/>
|
||||
</a>
|
||||
<span t-if="question.has_validated_answer and question.forum_id.mode == 'questions'"
|
||||
title="Solved"
|
||||
@@ -35,9 +35,9 @@
|
||||
|
||||
<!-- Toggle Tags on click -->
|
||||
<t t-if="tag and tag.name == question_tag.name" t-set="click_action"
|
||||
t-value="'/forum/' + slug(question_tag.forum_id) + '?' + keep_query( 'search', 'sorting', 'my')"/>
|
||||
t-value="'/forum/' + slug(question_tag.forum_id) + '?' + keep_query( 'search', 'sorting', 'my', 'create_uid',)"/>
|
||||
<t t-else="" t-set="click_action"
|
||||
t-value="'/forum/' + slug(question_tag.forum_id) + '/tag/' + slug(question_tag) + '/questions?' + keep_query( 'search', 'sorting', 'my', filters='tag')"/>
|
||||
t-value="'/forum/' + slug(question_tag.forum_id) + '/tag/' + slug(question_tag) + '/questions?' + keep_query( 'search', 'sorting', 'my', 'create_uid', filters='tag')"/>
|
||||
|
||||
<a t-att-href="click_action"
|
||||
t-attf-class="badge position-relative z-index-1 #{ 'text-bg-secondary' if tag and tag.name == question_tag.name else 'text-bg-light' } fw-normal"
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
data-bs-placement="top">
|
||||
<t t-set="user_profile_url" t-value="False"/>
|
||||
<t t-if="'forum_id' in object and (object.create_uid.id == request.session.uid or object.create_uid.sudo().website_published)">
|
||||
<t t-set="user_profile_url" t-valuef="/forum/#{ slug(object.forum_id) }/user/#{ object.create_uid.id }?forum_origin=#{ request.httprequest.path }"/>
|
||||
<t t-set="user_profile_url" t-valuef="/forum/user/#{ object.create_uid.id }?forum_id=#{ object.forum_id.id }&forum_origin=#{ request.httprequest.path }"/>
|
||||
</t>
|
||||
<a t-if="show_image" t-att-href="user_profile_url or '#'" t-attf-class="o_wforum_author_pic position-relative #{ 'pe-none' if not user_profile_url else '' }">
|
||||
<img t-attf-class="o_wforum_avatar rounded-circle #{'me-2' if show_name or show_date or show_karma else '' } #{_image_classes}" t-att-src="website.image_url(object.create_uid, 'avatar_128', '40x40')" alt="Avatar"/>
|
||||
|
||||
@@ -57,10 +57,23 @@
|
||||
<t t-set="is_profile" t-value="true"/>
|
||||
<div role="tabpanel" class="o_wforum_profile_tab tab-pane" id="questions">
|
||||
<div class="mb-4">
|
||||
<h5 class="border-bottom pb-1">
|
||||
<h5 class="border-bottom pb-1 d-flex align-items-center justify-content-between">
|
||||
Questions
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
<t t-if="count_questions > 0" class="float-end" t-call="website.website_search_box_input">
|
||||
<t t-set="_form_classes" t-valuef="d-flex flex-row align-items-center flex-wrap float-end"/>
|
||||
<t t-set="search_type" t-valuef="forums"/>
|
||||
<t t-if="forum_id" t-set="action" t-value="'/forum/%s%s' % (forum_id, ('/tag/%s/questions' % slug(tag)) if tag else '')"/>
|
||||
<t t-else="" t-set="action" t-value="'/forum/all%s' % (('/tag/%s/questions' % slug(tag)) if tag else '')"/>
|
||||
<t t-set="display_description" t-value="true"/>
|
||||
<t t-set="display_detail" t-valuef="false"/>
|
||||
<t t-set="placeholder" t-valuef="Search Questions..."/>
|
||||
<input type="hidden" name="create_uid" t-att-value="user.id"/>
|
||||
<input t-if="filters" type="hidden" name="filters" t-att-value="filters"/>
|
||||
<input t-if="my_profile" type="hidden" name="my" t-att-value="mine"/>
|
||||
<input t-if="sorting" type="hidden" name="sorting" t-att-value="sorting"/>
|
||||
</t>
|
||||
</h5>
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
<t t-if="questions">
|
||||
<div class="mb-1" t-foreach="questions" t-as="question">
|
||||
<t t-call="website_forum.display_post"/>
|
||||
@@ -101,10 +114,24 @@
|
||||
</div>
|
||||
<div role="tabpanel" class="o_wforum_profile_tab tab-pane" id="answers">
|
||||
<div class="mb-4">
|
||||
<h5 class="border-bottom pb-1">
|
||||
<h5 class="border-bottom pb-1 d-flex align-items-center justify-content-between">
|
||||
Answers
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
<t t-if="count_questions > 0" class="float-end" t-call="website.website_search_box_input">
|
||||
<t t-set="_form_classes" t-valuef="d-flex flex-row align-items-center flex-wrap float-end"/>
|
||||
<t t-set="search_type" t-valuef="forums"/>
|
||||
<t t-if="forum_id" t-set="action" t-value="'/forum/%s%s' % (forum_id, '/tag/%s/questions' % slug(tag)) if tag else ''"/>
|
||||
<t t-else="" t-set="action" t-value="'/forum/all%s' % (('/tag/%s/questions' % slug(tag)) if tag else '')"/>
|
||||
<t t-set="display_description" t-value="true"/>
|
||||
<t t-set="display_detail" t-valuef="false"/>
|
||||
<t t-set="placeholder" t-valuef="Search Answers..."/>
|
||||
<input type="hidden" name="author" t-att-value="user.id"/>
|
||||
<input t-if="filters" type="hidden" name="filters" t-att-value="filters"/>
|
||||
<input t-if="my_profile" type="hidden" name="my" t-att-value="mine"/>
|
||||
<input t-if="sorting" type="hidden" name="sorting" t-att-value="sorting"/>
|
||||
<input type="hidden" name="include_answers" t-att-value="True"/>
|
||||
</t>
|
||||
</h5>
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
|
||||
<t t-if="answers">
|
||||
<div class="mb-1" t-foreach="answers" t-as="answer">
|
||||
@@ -127,16 +154,31 @@
|
||||
</div>
|
||||
<div role="tabpanel" class="o_wforum_profile_tab tab-pane" id="votes" t-if="uid == user.id">
|
||||
<div class="mb-4">
|
||||
<h5 class="border-bottom pb-1">Votes</h5>
|
||||
<h5 class="border-bottom pb-1 flex align-items-center justify-content-between" style="height:43px;">
|
||||
Votes
|
||||
<t t-if="my_profile" class="float-end" t-call="website.website_search_box_input">
|
||||
<t t-set="_form_classes" t-valuef="d-flex flex-row align-items-center flex-wrap float-end"/>
|
||||
<t t-set="search_type" t-valuef="forums"/>
|
||||
<t t-set="action" t-value="'/forum/%s%s' % (forum_id or 'all', '/tag/%s/questions' % slug(tag) if tag else '')"/>
|
||||
<t t-set="display_description" t-value="true"/>
|
||||
<t t-set="display_detail" t-valuef="false"/>
|
||||
<t t-set="placeholder" t-valuef="Search Posts..."/>
|
||||
<input type="hidden" name="my" value="upvoted"/>
|
||||
<input t-if="filters" type="hidden" name="filters" t-att-value="filters"/>
|
||||
<input t-if="sorting" type="hidden" name="sorting" t-att-value="sorting"/>
|
||||
<input type="hidden" name="include_answers" t-att-value="True"/>
|
||||
</t>
|
||||
</h5>
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
<t t-call="website_forum.user_votes"/>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="o_wforum_profile_tab tab-pane" id="activity" t-if="uid == user.id">
|
||||
<div class="mb-4">
|
||||
<h5 class="border-bottom pb-1">
|
||||
<h5 class="border-bottom pb-1 d-flex align-items-center justify-content-between" style="height:43px;">
|
||||
Activities
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
</h5>
|
||||
<t t-call="website_forum.forum_filter_tag"/>
|
||||
<t t-call="website_forum.display_activities"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -182,17 +224,21 @@
|
||||
<template id="user_votes" name="Forum User Votes">
|
||||
<div t-foreach="vote_post" t-as="vote" class="card mb-2">
|
||||
<div class="card-body">
|
||||
<span t-if="vote.vote == '1'" class="fa fa-thumbs-up text-success me-2" role="img" aria-label="Positive vote" title="Positive vote"/>
|
||||
<span t-if="vote.vote == '-1'" class="fa fa-thumbs-down text-warning me-2" role="img" aria-label="Negative vote" title="Negative vote"/>
|
||||
<span t-field="vote.post_id.create_date"/>
|
||||
<span t-if="vote.vote == '1'" class="fa fa-thumbs-up text-success" style="margin-left:30px" role="img" aria-label="Positive vote" title="Positive vote"/>
|
||||
<span t-if="vote.vote == '-1'" class="fa fa-thumbs-down text-warning" style="margin-left:30px" role="img" aria-label="Negative vote" title="Negative vote"/>
|
||||
<a t-if="vote.post_id.parent_id" class="ms-2" t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/#{ vote.post_id.parent_id.id }/#answer-#{ vote.post_id.id }"
|
||||
t-out="vote.post_id.parent_id.name"/>
|
||||
<a t-else="" class="ms-2 text-black" t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/#{ vote.post_id.id }"
|
||||
t-out="vote.post_id.name"/>
|
||||
<a t-if="vote.post_id.parent_id" class="ms-2" t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/#{ vote.post_id.parent_id.id }/#answer-#{ vote.post_id.id }" t-out="vote.post_id.parent_id.name"/>
|
||||
<a t-else="" class="text-black ms-2" t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/#{ vote.post_id.id }" t-out="vote.post_id.name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb16" t-if="not vote_post">
|
||||
<p class="text-muted">You haven't given any votes yet.</p>
|
||||
<div t-if="my_profile" class="text-muted">
|
||||
Help moderating the forums by upvoting and downvoting posts. <br />
|
||||
<a href="/forum/" class="btn-link">
|
||||
<i class="fa fa-arrow-right"></i> Go To Forums
|
||||
</a>
|
||||
</div>
|
||||
<p t-else="" class="text-muted">You haven't given any votes yet.</p>
|
||||
</div>
|
||||
</template>
|
||||
</data></odoo>
|
||||
|
||||
@@ -46,28 +46,36 @@ publicWidget.registry.websiteProfileEditor = publicWidget.Widget.extend({
|
||||
'click .o_forum_profile_pic_edit': '_onEditProfilePicClick',
|
||||
'change .o_forum_file_upload': '_onFileUploadChange',
|
||||
'click .o_forum_profile_pic_clear': '_onProfilePicClearClick',
|
||||
'click .o_forum_profile_bio_edit': '_onProfileBioEditClick',
|
||||
'click .o_forum_profile_bio_cancel_edit': '_onProfileBioCancelEditClick',
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: async function () {
|
||||
var def = this._super.apply(this, arguments);
|
||||
const def = this._super.apply(this, arguments);
|
||||
if (this.editableMode) {
|
||||
return def;
|
||||
}
|
||||
|
||||
var $textarea = this.$('textarea.o_wysiwyg_loader');
|
||||
const $textarea = this.$("textarea.o_wysiwyg_loader");
|
||||
|
||||
this._wysiwyg = await loadWysiwygFromTextarea(this, $textarea[0], {
|
||||
const options = {
|
||||
recordInfo: {
|
||||
context: this._getContext(),
|
||||
res_model: 'res.users',
|
||||
res_id: parseInt(this.$('input[name=user_id]').val()),
|
||||
res_model: "res.users",
|
||||
res_id: parseInt(this.$("input[name=user_id]").val()),
|
||||
},
|
||||
resizable: true,
|
||||
userGeneratedContent: true,
|
||||
});
|
||||
};
|
||||
|
||||
if ($textarea[0].attributes.placeholder) {
|
||||
options.placeholder = $textarea[0].attributes.placeholder.value;
|
||||
}
|
||||
|
||||
this._wysiwyg = await loadWysiwygFromTextarea(this, $textarea[0], options);
|
||||
|
||||
return Promise.all([def]);
|
||||
},
|
||||
@@ -113,6 +121,30 @@ publicWidget.registry.websiteProfileEditor = publicWidget.Widget.extend({
|
||||
type: 'hidden',
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onProfileBioEditClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
ev.currentTarget.classList.add("d-none");
|
||||
document.querySelector(".o_forum_profile_bio_cancel_edit").classList.remove("d-none");
|
||||
document.querySelector(".o_forum_profile_bio").classList.add("d-none");
|
||||
document.querySelector(".o_forum_profile_bio_form").classList.remove("d-none");
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onProfileBioCancelEditClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
ev.currentTarget.classList.add("d-none");
|
||||
document.querySelector(".o_forum_profile_bio_edit").classList.remove("d-none");
|
||||
document.querySelector(".o_forum_profile_bio_form").classList.add("d-none");
|
||||
document.querySelector(".o_forum_profile_bio").classList.remove("d-none");
|
||||
},
|
||||
});
|
||||
|
||||
publicWidget.registry.websiteProfileNextRankCard = publicWidget.Widget.extend({
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="my-3 mb-0 pt-2 border-top">
|
||||
<label class="text-primary" for="user_website_published" t-if="user.id == uid"><span class="fw-bold">Public profile</span></label>
|
||||
<label class="text-primary" for="user_website_published" t-if="user.id == uid"><span class="fw-bold">Public Profile</span></label>
|
||||
<div class=" mb-0 float-end" t-if="user.id == uid">
|
||||
<input type="checkbox" class="mt8" name="website_published" id="user_website_published" value="True" t-if="not user.website_published"/>
|
||||
<input type="checkbox" class="mt8" name="website_published" id="user_website_published" value="True" checked="checked" t-if="user.website_published"/>
|
||||
@@ -156,7 +156,7 @@
|
||||
<div class="mb-3 col-12">
|
||||
<label class="mb-1 text-primary" for="description"><span class="fw-bold">Biography</span></label>
|
||||
<textarea name="description" id="description" style="min-height: 120px"
|
||||
class="form-control o_wysiwyg_loader"><t t-esc="user.partner_id.website_description"/></textarea>
|
||||
class="form-control o_wysiwyg_loader" placeholder="Write a few words about yourself..."><t t-out="user.partner_id.website_description"/></textarea>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="submit" class="btn btn-primary o_wprofile_submit_btn">Update</button>
|
||||
@@ -257,10 +257,9 @@
|
||||
<th><small class="fw-bold">Joined</small></th>
|
||||
<td><span t-field="user.create_date" t-options='{"format": "d MMM Y"}'/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr t-if="user.badge_ids">
|
||||
<th><small class="fw-bold">Badges</small></th>
|
||||
<td t-if="user.badge_ids" t-esc="len(user.badge_ids.filtered(lambda b: b.badge_id.website_published))"/>
|
||||
<td t-else="">0</td>
|
||||
<td t-esc="len(user.badge_ids.filtered(lambda b: b.badge_id.website_published))"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -277,7 +276,7 @@
|
||||
</ul>
|
||||
<div class="tab-content py-4 o_wprofile_tabs_content mb-4" id="profile_extra_info_tabcontent">
|
||||
<div role="tabpanel" t-attf-class="tab-pane #{ 'show active' if not active_tab or active_tab == 'about' else '' }" id="profile_tab_content_about">
|
||||
<div class="o_wprofile_email_validation_container mb16 mt16">
|
||||
<div class="o_wprofile_email_validation_container">
|
||||
<t t-call="website_profile.email_validation_banner">
|
||||
<t t-set="redirect_url" t-value="'/profile/user/%s' % user.id"/>
|
||||
<t t-set="additional_validation_email_message"/>
|
||||
@@ -287,9 +286,18 @@
|
||||
<h5 class="border-bottom pb-1">Badges</h5>
|
||||
<t t-call="website_profile.user_badges"></t>
|
||||
</div>
|
||||
<div t-if="user.partner_id.website_description" class="mb32">
|
||||
<div t-if="user.partner_id.website_description" class="o_wprofile_editor_form mb32">
|
||||
<t t-if="request.env.user == user and user.karma != 0 or request.env.user._is_admin()">
|
||||
<a href="#" class="o_forum_profile_bio_edit btn btn-link float-end">
|
||||
<i class="fa fa-pencil me-1"/>Edit
|
||||
</a>
|
||||
<a href="#" class="o_forum_profile_bio_cancel_edit btn btn-link float-end d-none">
|
||||
<i class="fa fa-close me-1"/>Cancel
|
||||
</a>
|
||||
</t>
|
||||
<h5 class="border-bottom pb-1">Biography</h5>
|
||||
<span t-field="user.partner_id.website_description"/>
|
||||
<span class="o_forum_profile_bio text-break" t-field="user.partner_id.website_description"/>
|
||||
<t t-call="website_profile.user_biography_editor"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -298,6 +306,29 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="user_biography_editor" name="Edit User Biography">
|
||||
<form t-attf-action="/profile/user/save" method="post" role="form" class="o_forum_profile_bio_form js_website_submit_form row d-none">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input name="user_id" t-att-value="user.id" type="hidden"/>
|
||||
<input name="name" t-att-value="user.name" type="hidden"/>
|
||||
<input name="website" t-att-value="user.partner_id.website" type="hidden"/>
|
||||
<input name="email" t-att-value="user.partner_id.email" type="hidden"/>
|
||||
<input name="city" t-att-value="user.partner_id.city" type="hidden"/>
|
||||
<input name="country" t-att-value="user.partner_id.country_id.id" type="hidden"/>
|
||||
<div class="row">
|
||||
<div class="mb-1 col-12">
|
||||
<textarea name="description" id="description" style="min-height: 120px"
|
||||
class="form-control o_wysiwyg_loader" placeholder="Write a few words about yourself...">
|
||||
<t t-out="user.partner_id.website_description"/>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="submit" class="btn btn-primary o_wprofile_submit_btn">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<template id="profile_next_rank_card" name="Profile Next Rank Card">
|
||||
<div class="o_wprofile_progress_circle">
|
||||
<svg viewBox="0 0 36 36" class="o_pc_circular_chart">
|
||||
@@ -375,14 +406,21 @@
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="mb-3 d-inline-block" t-if="not user.badge_ids">
|
||||
<div class="mb-3" t-elif="request.env.user == user">
|
||||
Badges are your collection of achievements. Wear them proudly! <br />
|
||||
<a t-if="not user.badge_ids and badge_category" t-attf-href="/profile/ranks_badges?badge_category=#{badge_category}&url_origin=#{request.httprequest.path}&name_origin=#{user.name}"
|
||||
class="btn-link"><i class="fa fa-arrow-right"/> Get Badges</a>
|
||||
<a t-else="" t-attf-href="/profile/ranks_badges?url_origin=#{request.httprequest.path}&name_origin=#{user.name}"
|
||||
class="btn-link"><i class="fa fa-arrow-right"/> Get Badges</a>
|
||||
</div>
|
||||
<div t-else="" class="mb-3 d-inline-block">
|
||||
<p class="text-muted">No badges yet!</p>
|
||||
</div>
|
||||
<div class="text-end d-inline-block pull-right">
|
||||
<div t-if="request.env.user.id != user.id" class="text-end d-inline-block pull-right">
|
||||
<a t-if="not user.badge_ids and badge_category" t-attf-href="/profile/ranks_badges?badge_category=#{badge_category}&url_origin=#{request.httprequest.path}&name_origin=#{user.name}"
|
||||
class="btn btn-link btn-sm"><i class="oi oi-arrow-right"/> All Badges</a>
|
||||
class="btn-link btn-sm"><i class="oi oi-arrow-right"/> All Badges</a>
|
||||
<a t-else="" t-attf-href="/profile/ranks_badges?url_origin=#{request.httprequest.path}&name_origin=#{user.name}"
|
||||
class="btn btn-link btn-sm"><i class="oi oi-arrow-right me-1"/>All Badges</a>
|
||||
class="btn-link btn-sm"><i class="oi oi-arrow-right me-1"/>All Badges</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1574,6 +1574,7 @@ class WebsiteSlides(WebsiteProfile):
|
||||
'courses_ongoing': courses_ongoing,
|
||||
'is_profile_page': True,
|
||||
'badge_category': 'slides',
|
||||
'my_profile': request.env.user.id == user.id,
|
||||
}
|
||||
return values
|
||||
|
||||
|
||||
@@ -17,8 +17,14 @@
|
||||
<t t-if="courses_completed" t-call="website_slides.display_course">
|
||||
<t t-set="courses" t-value="courses_completed"></t>
|
||||
</t>
|
||||
<div t-elif="request.env.user == user" class="text-muted d-inline-block">
|
||||
Go through all its content to see a Course in this section. <br />
|
||||
<a href="/slides/" class="btn-link">
|
||||
<i class="fa fa-arrow-right"></i> Start Learning
|
||||
</a>
|
||||
</div>
|
||||
<div t-else="" class="text-muted d-inline-block">No completed courses yet!</div>
|
||||
<div class="text-end d-inline-block pull-right">
|
||||
<div t-if="request.env.user != user" class="text-end d-inline-block pull-right">
|
||||
<a href="/slides/all" class="btn btn-link btn-sm"><i class="oi oi-arrow-right me-1"/>All Courses</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,6 +33,12 @@
|
||||
<t t-if="courses_ongoing" t-call="website_slides.display_course">
|
||||
<t t-set="courses" t-value="courses_ongoing"></t>
|
||||
</t>
|
||||
<p t-elif="request.env.user == user" class="text-muted">
|
||||
All the courses you attend will appear here. <br />
|
||||
<a href="/slides/" class="btn-link">
|
||||
<i class="fa fa-arrow-right"></i> Start Learning
|
||||
</a>
|
||||
</p>
|
||||
<p t-else="" class="text-muted">No ongoing courses yet!</p>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</template>
|
||||
<template name="Replace Breadcrumb Root" id="website_slides_forum_breadcrumb" inherit_id="website_forum.forum_model_nav" active="True">
|
||||
<xpath expr="//nav[@id='o_wforum_nav']" position="before">
|
||||
<t t-if="forum.slide_channel_id" t-set="breadcrumb_kind" t-value="'slides'"/>
|
||||
<t t-if="forum and forum.slide_channel_id" t-set="breadcrumb_kind" t-value="'slides'"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_wforum_breadcrumb_root_single')]" postition="inside">
|
||||
<ol t-if="breadcrumb_kind == 'slides'" class="breadcrumb col-10 col-lg-6 mb-0 p-0">
|
||||
|
||||
@@ -92,13 +92,21 @@
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-elif="my_profile">
|
||||
<div class="text-muted d-inline-block">
|
||||
Certifications are exams that you successfully passed. <br />
|
||||
<a href="/slides/all?slide_type=certification" class="btn-link">
|
||||
<i class="fa fa-arrow-right"></i> Get Certified
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="text-muted d-inline-block">No certifications yet!</div>
|
||||
<div class="text-end d-inline-block pull-right">
|
||||
<a href="/slides/all?slide_category=certification" class="btn btn-link btn-sm"><i class="oi oi-arrow-right me-1"/>All Certifications</a>
|
||||
</div>
|
||||
</t>
|
||||
<div class="text-end d-inline-block pull-right">
|
||||
<a href="/slides/all?slide_category=certification" class="btn btn-link btn-sm"><i class="oi oi-arrow-right me-1"/>All Certifications</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="top3_user_card" inherit_id="website_profile.top3_user_card">
|
||||
|
||||
Reference in New Issue
Block a user