This commit is contained in:
Christophe Monniez 2022-09-20 07:42:50 +02:00
parent 0ea9c4aefe
commit 147fc73078
6 changed files with 185 additions and 67 deletions

View File

@ -25,14 +25,12 @@ def route(routes, **kw):
@functools.wraps(f)
def response_wrap(*args, **kwargs):
projects = request.env['runbot.project'].search([])
more = request.httprequest.cookies.get('more', False) == '1'
filter_mode = request.httprequest.cookies.get('filter_mode', 'all')
keep_search = request.httprequest.cookies.get('keep_search', False) == '1'
cookie_search = request.httprequest.cookies.get('search', '')
refresh = kwargs.get('refresh', False)
nb_build_errors = request.env['runbot.build.error'].search_count([('random', '=', True), ('parent_id', '=', False)])
nb_assigned_errors = request.env['runbot.build.error'].search_count([('responsible', '=', request.env.user.id)])
kwargs['more'] = more
kwargs['projects'] = projects
response = f(*args, **kwargs)
@ -47,7 +45,6 @@ def route(routes, **kw):
project = response.qcontext.get('project') or projects[0]
response.qcontext['projects'] = projects
response.qcontext['more'] = more
response.qcontext['keep_search'] = keep_search
response.qcontext['search'] = search
response.qcontext['current_path'] = request.httprequest.full_path
@ -78,9 +75,8 @@ class Runbot(Controller):
@o_route([
'/runbot/submit'
], type='http', auth="public", methods=['GET', 'POST'], csrf=False)
def submit(self, more=False, redirect='/', keep_search=False, category=False, filter_mode=False, update_triggers=False, **kwargs):
def submit(self, redirect='/', keep_search=False, category=False, filter_mode=False, update_triggers=False, **kwargs):
response = werkzeug.utils.redirect(redirect)
response.set_cookie('more', '1' if more else '0')
response.set_cookie('keep_search', '1' if keep_search else '0')
response.set_cookie('filter_mode', filter_mode or 'all')
response.set_cookie('category', category or '0')
@ -101,8 +97,9 @@ class Runbot(Controller):
@route(['/',
'/runbot',
'/runbot/<model("runbot.project"):project>',
'/runbot/<model("runbot.project"):project>/search/<search>'], website=True, auth='public', type='http')
def bundles(self, project=None, search='', projects=False, refresh=False, **kwargs):
'/runbot/<model("runbot.project"):project>/search/<search>',
'/runbot/page/<int:page>'], website=True, auth='public', type='http')
def bundles(self, limit=40, page=1, project=None, search='', projects=False, refresh=False, **kwargs):
search = search if len(search) < 60 else search[:60]
env = request.env
categories = env['runbot.category'].search([])
@ -149,8 +146,21 @@ class Runbot(Controller):
case when "runbot_bundle".sticky then "runbot_bundle".version_number end collate "C" desc,
"runbot_bundle".last_batch desc
"""
query.limit=40
bundles = env['runbot.bundle'].browse(query)
bundle_count = request.env['runbot.bundle.pr'].search_count(domain)
limit = min(float(limit), 200)
pager = request.website.pager(
url='/runbot/',
url_args={'search': search},
total=bundle_count,
scope=3,
page=page,
step=limit,
)
query.limit = limit
query.offset = pager.get('offset', 0)
bundles_pr = env['runbot.bundle.pr'].browse(query)
bundles = env['runbot.bundle'].browse(bundles_pr.ids)
category_id = int(request.httprequest.cookies.get('category') or 0) or request.env['ir.model.data']._xmlid_to_res_id('runbot.default_category')
@ -161,6 +171,7 @@ class Runbot(Controller):
triggers = env['runbot.trigger'].search([('project_id', '=', project.id)])
context.update({
'pager': pager,
'active_category_id': category_id,
'bundles': bundles,
'project': project,
@ -168,6 +179,14 @@ class Runbot(Controller):
'trigger_display': trigger_display,
})
pr_filters = {
'all': { 'text': 'All', 'domain': False},
'has_pr': { 'text': 'With Pull Request(s)', 'domain': ('pr_count', '>', 0)},
'has_no_pr': { 'text': 'Without Pull Request(s)', 'domain': ('pr_count', '=', 0)},
'has_open_pr': { 'text': 'With Open Pull Request(s)', 'domain': ('pr_open_count', '>', 0)},
'has_no_open_pr': { 'text': 'Without Open Pull Request(s)', 'domain': ('pr_open_count', '=', 0)},
}
context.update({'message': request.env['ir.config_parameter'].sudo().get_param('runbot.runbot_message')})
res = request.render('runbot.bundles', context)
return res

View File

@ -270,7 +270,10 @@ class BundlePr(models.Model):
id = fields.Many2one('runbot.bundle', string='Bundle', readonly=True)
name = fields.Char(string='Bundle Name', readonly=True)
project_id = fields.Many2one('runbot.project', readonly=True)
no_build = fields.Boolean('No build', readonly=True)
last_batch = fields.Many2one('runbot.batch', readonly=True)
is_base = fields.Boolean('Is base', readonly=True)
sticky = fields.Boolean('Sticky', readonly=True)
owner_id = fields.Many2one('res.users', string='Bundle Owner', readonly=True)
tags = fields.Char('Comma Separated Tags', readonly=True)
branch_count = fields.Integer('Branch count', readonly=True)
@ -278,6 +281,7 @@ class BundlePr(models.Model):
pr_open_count = fields.Integer('Open PR count', readonly=True)
pr_closed_count = fields.Integer('Closed PR count', readonly=True)
def init(self):
""" Create an SQL view for bundle """
tools.drop_view_if_exists(self._cr, 'runbot_bundle_pr')
@ -287,7 +291,10 @@ class BundlePr(models.Model):
runbot_bundle.id AS id,
runbot_bundle.name AS name,
runbot_bundle.project_id AS project_id,
runbot_bundle.no_build AS no_build,
runbot_bundle.last_batch AS last_batch,
runbot_bundle.is_base AS is_base,
runbot_bundle.sticky AS sticky,
runbot_bundle.owner_id AS owner_id,
STRING_AGG(runbot_bundle_tag.name,',') AS tags,
count(runbot_branch.id) AS branch_count,

View File

@ -30,3 +30,17 @@ function copyToClipboard(text) {
}
navigator.clipboard.writeText(text);
}
function toggleMoreInfo() {
let batches_commits_infos = document.getElementsByClassName("batch_commits");
for (let i = 0; i < batches_commits_infos.length; i++) {
info_block = batches_commits_infos[i];
console.log(info_block.style.display);
if (info_block.style.display === "none") {
info_block.style.display = "block";
}
else {
info_block.style.display = "none";
}
}
}

View File

@ -3,6 +3,66 @@
<data>
<template id="runbot.bundle_list">
<t t-call="runbot.layout">
<t t-set="nav_form">
<t t-call="website.website_search_box_input">
<t t-set="_form_classes" t-valuef="mt8 float-right"/>
<t t-set="action" t-valuef="/runbot/bundle"/>
<t t-set="placeholder">Search Bundle Names</t>
<t t-set="search" t-value="search"/>
<div class="d-flex">
<span class="navbar-brand h4 my-0 mr-auto">Filters</span>
<ul class="nav">
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-filter"/>PR
</a>
<div class="dropdown-menu">
<t t-foreach="pr_filters" t-as="pr_filter">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', pr_filter=pr_filter if pr_filter != 'all' else None) }}">
<span t-esc="pr_filters[pr_filter].get('text')"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-users"/>Team
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=None) }}">
<span>Any</span>
</a>
<t t-foreach="teams" t-as="team">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=team.id) }}">
<span t-esc="team.name"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-tags"/>Tags
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=None) }}">
<span>Any</span>
</a>
<t t-foreach="tags" t-as="tag">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=tag.id) }}">
<span t-esc="tag.name"/>
</a>
</t>
</div>
</li>
</ul>
</div>
</t>
</t>
<t t-call="runbot.bundle_list_top_bar" />
<div class="container-fluid">
<div class="row">
@ -57,63 +117,57 @@
<div class="container-fluid">
<div class="d-flex flex-column flex-sm-row justify-content-between w-100">
<t t-call="website.pager" />
<span class="navbar-brand h4 my-0 mr-auto">Filters</span>
<ul class="nav">
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-filter"/>PR
</a>
<div class="dropdown-menu">
<t t-foreach="pr_filters" t-as="pr_filter">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', pr_filter=pr_filter if pr_filter != 'all' else None) }}">
<span t-esc="pr_filters[pr_filter].get('text')"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-users"/>Team
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=None) }}">
<span>Any</span>
<div class="d-flex">
<span class="navbar-brand h4 my-0 mr-auto">Filters</span>
<ul class="nav">
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-filter"/>PR
</a>
<t t-foreach="teams" t-as="team">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=team.id) }}">
<span t-esc="team.name"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-tags"/>Tags
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=None) }}">
<span>Any</span>
<div class="dropdown-menu">
<t t-foreach="pr_filters" t-as="pr_filter">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', pr_filter=pr_filter if pr_filter != 'all' else None) }}">
<span t-esc="pr_filters[pr_filter].get('text')"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-users"/>Team
</a>
<t t-foreach="tags" t-as="tag">
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=tag.id) }}">
<span t-esc="tag.name"/>
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=None) }}">
<span>Any</span>
</a>
</t>
</div>
</li>
</ul>
<div class="col-md-4 d-none d-md-flex flex-row align-items-center justify-content-end">
<t t-call="website.website_search_box_input">
<t t-set="_form_classes" t-valuef="mt8 float-right"/>
<t t-set="action" t-valuef="/runbot/bundle"/>
<t t-set="placeholder">Search Bundle Names</t>
<t t-set="search" t-value="search"/>
</t>
<t t-foreach="teams" t-as="team">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', team_id=team.id) }}">
<span t-esc="team.name"/>
</a>
</t>
</div>
</li>
<li class="nav-item dropdown mr-2 my-1">
<a href="#" role="button" class="btn dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-tags"/>Tags
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=None) }}">
<span>Any</span>
</a>
<t t-foreach="tags" t-as="tag">
<a class="dropdown-item d-flex align-items-center justify-content-between"
t-attf-href="/runbot/bundle?{{ keep_query('*', tag_id=tag.id) }}">
<span t-esc="tag.name"/>
</a>
</t>
</div>
</li>
</ul>
</div>
</div>
</div>

View File

@ -4,6 +4,7 @@
<template id="runbot.bundles">
<t t-call='runbot.layout'>
<t t-set="nav_form">
<t t-call="website.pager" />
<form class="form-inline my-2 my-lg-0" role="search" t-att-action="qu(search='')" method="get">
<div class="input-group md-form form-sm form-2 pl-0">
<input class="form-control my-0 py-1" type="text" placeholder="Search" aria-label="Search" name="search" t-att-value="search"/>
@ -73,6 +74,9 @@
</div>
</div>
</div>
<div class="pull-right">
<t t-call="website.pager" />
</div>
</t>
</template>
@ -105,7 +109,7 @@
</t>
<div class="slot_filler" t-foreach="range(10)" t-as="x"/>
</div>
<div t-if='more' class="batch_commits">
<div class="batch_commits" style="display: none;">
<div t-foreach="batch.commit_link_ids.sorted(lambda cl: (cl.commit_id.repo_id.sequence, cl.commit_id.repo_id.id))" t-as="commit_link" class="one_line">
<a t-attf-href="/runbot/commit/#{commit_link.commit_id.id}" t-attf-class="badge badge-light batch_commit match_type_{{commit_link.match_type}}">

View File

@ -53,6 +53,14 @@
</t>
</t>
<li class="nav-item divider"/>
<li>
<a href="#" class="nav-link" title="Toggle More Batch Infos" aria-label="Toggle More Batch Infos" onclick="toggleMoreInfo()">
<i t-attf-class="fa fa-info"/>
</a>
</li>
<li class="nav-item divider"/>
<t t-call="runbot.filter_dropdown" />
<li class="nav-item divider"/>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-gear"/>
@ -61,10 +69,6 @@
<form class="px-4 py-3" method="post" action="/runbot/submit">
<input type="hidden" name="save" value="1"/>
<input type="hidden" name="redirect" t-att-value="current_path"/>
<div class="text-nowrap">
<input type="checkbox" name="more" id="more" t-att-checked="more"/>
<label for="more">More info</label>
</div>
<div class="text-nowrap">
<input type="checkbox" name="keep_search" id="keep_search" t-att-checked="keep_search"/>
<label for="keep_search">Persistent search</label>
@ -355,5 +359,21 @@
</t>
</div>
</template>
<template id="runbot.filter_dropdown">
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-filter"/>
</a>
<div class="dropdown-menu" role="menu">
<t t-foreach="pr_filters" t-as="pr_filter">
<a class="dropdown-item d-flex align-items-center justify-content-between" t-attf-href="/runbot/bundle?{{ keep_query('*', pr_filter=pr_filter if pr_filter != 'all' else None) }}">
<span t-esc="pr_filters[pr_filter].get('text')"/>
</a>
</t>
<hr class="separator"/>
</div>
</li>
</template>
</data>
</odoo>