<odoo>
    <function model="website.page" name="write">
        <value eval="ref('website.homepage_page')"/>
        <value eval="{'active': False}"/>
    </function>

    <template id="link-pr" name="create a link to `pr`">
        <t t-set="title">
            <t t-if="pr.repository.group_id &lt;= env.user.groups_id">
                <t t-esc="pr.message.split('\n')[0]"/>
            </t>
        </t>
        <a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
           t-att-title="pr.blocked or title.strip()"
           t-att-target="target or None"
           t-att-class="classes or None"
        ><t t-esc="pr.display_name"/></a>
    </template>

    <template id="staging-statuses" name="dropdown statuses list of stagings">
        <div class="dropdown" t-if="staging.heads">
            <button class="btn btn-link dropdown-toggle"
                    type="button"
                    data-toggle="dropdown"
                    aria-haspopup="true"
                    aria-expanded="true"
                    t-attf-title="Staged at {{staging.staged_at}}Z"
            >
                <t t-out="0"/>
                <span class="caret"></span>
            </button>
            <div class="dropdown-menu staging-statuses">
                <a groups="runbot_merge.group_admin"
                   class="dropdown-item" role="menuitem"
                   t-attf-href="/web#id={{staging.id}}&amp;view_type=form&amp;model=runbot_merge.stagings"
                   target="new">
                    Open Staging
                </a>
                <t t-set="statuses" t-value="{(r, c): (s, t) for r, c, s, t in staging.statuses}"/>
                <t t-foreach="repo_statuses._for_staging(staging)" t-as="req">
                    <t t-set="st" t-value="statuses.get((req.repo_id.name, req.context)) or (None, None)"/>
                    <a t-att-href="st[1]" target="new" role="menuitem" t-attf-class="
                        dropdown-item
                            {{'bg-success' if st[0] == 'success'
                       else 'bg-danger' if st[0] in ('error', 'failure')
                       else 'bg-info' if st[0]
                       else 'bg-light'}}">
                        <t t-esc="req.repo_id.name"/>: <t t-esc="req.context"/>
                    </a>
                </t>
            </div>
        </div>
    </template>

    <template id="alerts">
        <div id="alerts" class="row text-center">
            <div class="alert alert-light col-md-12 h6 mb-0">
                <a href="/runbot_merge/changelog">Changelog</a>
            </div>
            <t t-set="stagingcron" t-value="env(user=1).ref('runbot_merge.staging_cron')"/>
            <div t-if="not stagingcron.active" class="alert alert-warning col-12 mb-0" role="alert">
                Staging is disabled, "ready" pull requests will not be staged.
            </div>
            <t t-set="mergecron" t-value="env(user=1).ref('runbot_merge.merge_cron')"/>
            <div t-if="not mergecron.active" class="alert alert-warning col-12 mb-0" role="alert">
                Merging is disabled, stagings will not be integrated.
            </div>
        </div>
    </template>

    <template id="dashboard" name="mergebot dashboard">
        <t t-call="website.layout">
            <div id="wrap"><div class="container-fluid">
                <t t-call="runbot_merge.alerts"/>
                <section t-foreach="projects.with_context(active_test=False)" t-as="project" class="row">
                    <h1 class="col-md-12"><t t-esc="project.name"/></h1>
                    <div class="col-md-12">
                        key:
                        <ul class="list-inline">
                            <li class="bg-success">success (hopefully merged)</li>
                            <li class="bg-info">ongoing</li>
                            <li class="bg-danger">failure</li>
                            <li class="bg-gray-lighter">cancelled</li>
                        </ul>
                    </div>
                    <section t-foreach="project.branch_ids" t-as="branch" t-if="branch.active" class="col-md-12">
                        <h2>
                            <a t-attf-href="/runbot_merge/{{branch.id}}">
                                <t t-esc="branch.name"/>
                            </a>
                        </h2>
                        <t t-call="runbot_merge.stagings"/>
                        <t t-set="splits" t-value="branch.split_ids"/>
                        <t t-set="ready_unstaged" t-value="
                            project.env['runbot_merge.pull_requests'].search([
                                ('target', '=', branch.id),
                                ('state', '=', 'ready'),
                                ('staging_id', '=', False),
                            ]) - splits.mapped('batch_ids.prs')
                        "/>
                        <t t-set="ready" t-value="ready_unstaged.filtered(lambda p: not p.blocked)"/>
                        <t t-set="blocked" t-value="ready_unstaged.filtered(lambda p: p.blocked)"/>
                        <div t-if="splits" class="splits bg-warning pr-awaiting">
                            <h5>
                                Splits
                                <small class="text-muted">will be staged next</small>
                            </h5>
                            <ul>
                                <li t-foreach="splits" t-as="split">
                                    <ul class="pr-listing list-inline list-unstyled mb0">
                                        <li t-foreach="split.mapped('batch_ids.prs')" t-as="pr">
                                            <t t-call="runbot_merge.link-pr"/>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </div>
                        <div t-if="ready" class="pr-listing pr-awaiting bg-warning">
                            <h5>Awaiting</h5>
                            <ul class="list-inline">
                                <li t-foreach="ready" t-as="pr">
                                    <t t-call="runbot_merge.link-pr"/>
                                </li>
                            </ul>
                        </div>
                        <div t-if="blocked" class="pr-listing pr-blocked bg-info">
                            <h5>Blocked</h5>
                            <ul class="list-inline">
                                <li t-foreach="blocked" t-as="pr">
                                    <t t-call="runbot_merge.link-pr"/>
                                </li>
                            </ul>
                        </div>
                        <t t-set="failed" t-value="
                            project.env['runbot_merge.pull_requests'].search([
                                ('target', '=', branch.id),
                                ('state', '=', 'error'),
                                ('staging_id', '=', False),
                            ])
                        "/>
                        <div t-if="failed" class="pr-listing pr-failed bg-danger">
                            <h5>Failed</h5>
                            <ul class="list-inline">
                                <li t-foreach="failed" t-as="pr">
                                    <t t-call="runbot_merge.link-pr"/>
                                </li>
                            </ul>
                        </div>
                    </section>
                </section>
            </div></div>
        </t>
    </template>
    <template id="stagings" name="mergebot branch stagings">
        <t t-set="repo_statuses" t-value="branch.project_id.repo_ids.having_branch(branch).status_ids"/>
        <ul class="list-unstyled stagings">
            <t t-foreach="branch.env['runbot_merge.stagings'].search([('target', '=', branch.id)], order='staged_at desc', limit=6)" t-as="staging">
                <t t-set="success" t-value="staging.state == 'success'"/>
                <t t-set="failure" t-value="staging.state == 'failure'"/>
                <t t-set="pending" t-value="staging.active and (not staging.state or staging.state == 'pending')"/>
                <t t-set="stateclass">
                    <t t-if="success">bg-success <t t-if="staging.active">bg-unmerged</t></t>
                    <t t-if="failure">bg-danger</t>
                    <t t-if="pending">bg-info</t>
                    <t t-if="not (success or failure or pending)">bg-gray-lighter</t>
                </t>
                <t t-set="decorationclass" >
                    <t t-if="4 > staging_index >= 2">d-none d-md-block</t>
                    <t t-if="staging_index >= 4">d-none d-lg-block</t>
                </t>
                <t t-set="title">
                    <t t-if="staging.state == 'ff_failed'">fast forward failed (<t t-esc="staging.reason"/>)</t>
                    <t t-if="staging.state == 'pending'">last status</t>
                </t>
                <!-- separate concatenation to avoid having line-break in title as some browsers trigger it -->
                <!-- write-date may have microsecond precision, strip that information -->
                <!-- use write-date under assumption that a staging is last modified when it ends -->
                <t t-set="title"><t t-esc="title.strip() or staging.reason"/> at <t t-esc="staging.write_date.replace(microsecond=0)"/>Z</t>
                <li t-attf-class="staging {{stateclass.strip()}} {{decorationclass.strip()}}" t-att-title="title">
                    <ul class="list-unstyled">
                        <li t-foreach="staging.batch_ids" t-as="batch" class="batch">
                            <t t-esc="batch.prs[:1].label"/>
                            <t t-foreach="batch.prs" t-as="pr">
                                <t t-call="runbot_merge.link-pr"/>
                            </t>
                        </li>
                    </ul>
                    <t t-call="runbot_merge.staging-statuses">
                        Staged <span t-field="staging.staged_at" t-options="{'widget': 'relative'}"/>
                    </t>
                </li>
            </t>
        </ul>
    </template>
    <template id="branch_stagings" name="mergebot stagings page">
        <t t-set="repo_statuses" t-value="branch.project_id.repo_ids.having_branch(branch).status_ids"/>
        <t t-call="website.layout">
            <div id="wrap"><div class="container-fluid">
                <section class="row">
                    <h1 class="col-md-12"><t t-esc="branch.project_id.name"/>: <t t-esc="branch.name"/></h1>
                </section>
                <table>
                    <t t-foreach="stagings" t-as="staging">
                        <t t-set="success"
                           t-value="staging.state == 'success'"/>
                        <t t-set="failure"
                           t-value="staging.state == 'failure'"/>
                        <t t-set="pending"
                           t-value="staging.active and (not staging.state or staging.state == 'pending')"/>
                        <t t-set="stateclass">
                            <t t-if="success">bg-success</t>
                            <t t-if="failure">bg-danger</t>
                            <t t-if="pending">bg-info</t>
                            <t t-if="not (success or failure or pending)">
                                bg-gray-lighter
                            </t>
                        </t>
                        <t t-set="title">
                            <t t-if="staging.state == 'canceled'">Cancelled:
                                <t t-esc="staging.reason"/>
                            </t>
                            <t t-if="staging.state == 'ff_failed'">Fast
                                Forward Failed
                            </t>
                            <t t-if="staging.state not in ('canceled', 'ff_failed')">
                                <t t-esc="staging.reason"/>
                            </t>
                        </t>
                        <tr t-att-class="stateclass"
                            style="border-bottom: 1px solid gainsboro; vertical-align: top">
                            <th t-att-title="title.strip() or None">
                                <t t-if="not staging.heads">
                                    <span t-field="staging.staged_at"
                                          t-options="{'format': 'yyyy-MM-dd\'T\'HH:mm:ssZ'}"/>
                                </t>
                                <t t-call="runbot_merge.staging-statuses">
                                    <span t-field="staging.staged_at"
                                          t-options="{'format': 'yyyy-MM-dd\'T\'HH:mm:ssZ'}"/>
                                </t>
                            </th>
                            <td>
                                <ul class="list-inline list-unstyled mb0">
                                    <t t-foreach="staging.batch_ids"
                                       t-as="batch">
                                        <t t-set="first_pr"
                                           t-value="batch.prs[-1:]"/>
                                        <li class="dropdown" t-if="first_pr">
                                            <button class="btn btn-link dropdown-toggle"
                                                    type="button"
                                                    data-toggle="dropdown"
                                                    aria-haspopup="true"
                                                    aria-expanded="true"
                                            >
                                                <t t-esc="first_pr.label"/>
                                                <span class="caret"></span>
                                            </button>
                                            <div class="dropdown-menu">
                                                <t t-foreach="batch.prs" t-as="pr">
                                                    <t t-call="runbot_merge.link-pr">
                                                        <t t-set="target">new</t>
                                                        <t t-set="classes">dropdown-item</t>
                                                    </t>
                                                </t>
                                            </div>
                                        </li>
                                    </t>
                                </ul>
                            </td>
                        </tr>
                    </t>
                </table>
                <t t-if="next">
                    <a t-attf-href="/runbot_merge/{{branch.id}}?until={{next}}">
                        Next >
                    </a>
                </t>
            </div></div>
        </t>
    </template>
    <template id="changelog" name="mergebot changelog">
        <t t-call="website.layout">
            <div id="wrap"><div class="container-fluid">
                <h1>Changelog</h1>
                <section t-foreach="entries" t-as="entry">
                    <h3 t-if="not entry_first" t-esc="entry"/>
                    <ul>
                        <li t-foreach="sorted(entry_value)" t-as="item">
                            <t t-out="item"/>
                        </li>
                    </ul>
                </section>
            </div></div>
        </t>
    </template>

    <template id="view_pull_request_info_merged">
        <div class="alert alert-success">
            Merged
            <t t-if="merged_head">
                at <a t-attf-href="https://github.com/{{pr.repository.name}}/commit/{{merged_head}}"><t t-esc="merged_head"/></a>
            </t>

            <t t-set="linked_prs" t-value="pr._linked_prs"/>
            <div t-if="linked_prs">
                Linked pull requests
                <ul>
                    <li t-foreach="linked_prs" t-as="linked">
                        <a t-att-href="linked.url" t-field="linked.display_name"/>
                    </li>
                </ul>
            </div>
        </div>
    </template>
    <template id="view_pull_request_info_closed">
        <div class="alert alert-light">
            Closed
        </div>
    </template>
    <template id="view_pull_request_info_error">
        <div class="alert alert-danger">
            Error:
            <span t-esc="pr.with_context(active_test=False).batch_ids[-1:].staging_id.reason">
                Unable to stage PR
            </span>
        </div>
    </template>
    <template id="view_pull_request_info_staging">
        <div class="alert alert-primary">
            Staged <span t-field="pr.staging_id.staged_at" t-options="{'widget': 'relative'}"/>.

            <t t-set="linked_prs" t-value="pr._linked_prs"/>
            <div t-if="linked_prs">
                Linked pull requests
                <ul>
                    <li t-foreach="linked_prs" t-as="linked">
                        <a t-att-href="linked.url" t-field="linked.display_name"/>
                    </li>
                </ul>
            </div>
        </div>
    </template>
    <template id="view_pull_request_info_open">
        <!-- nb: replicates `blocked`, maybe that should be split into various criteria? -->
        <div class="alert alert-info">
        <p t-if="pr.blocked" class="alert-danger">Blocked</p>
        <p t-else="" class="alert-success">Ready (waiting for staging)</p>
        <ul class="todo">
            <li t-att-class="'ok' if pr.squash or pr.merge_method else 'fail'">
                Merge method
            </li>
            <li t-att-class="'ok' if pr._approved else 'fail'">
                Review
            </li>
            <li t-att-class="'ok' if pr.state not in ('opened', 'approved') else ''">
                CI
                <ul class="todo">
                    <t t-foreach="pr.repository.status_ids._for_pr(pr)" t-as="ci">
                        <t t-set="st" t-value="statuses.get(ci.context.strip())"/>
                        <t t-set="result">
                            <t t-if="not st or st['state'] == 'pending'"></t>
                            <t t-elif="st['state'] in ('error', 'failure')">fail</t>
                            <t t-else="">ok</t>
                        </t>
                        <li t-att-class="result">
                            <a t-att-href="st.get('target_url') if st else None"><t t-esc="ci.context.strip()"/></a><t t-if="st and st.get('description')">: <t t-esc="st['description']"/></t>
                        </li>
                    </t>
                </ul>
            </li>
            <t t-set="linked_prs" t-value="pr._linked_prs"/>
            <li t-if="linked_prs" t-att-class="'ok' if all(l._ready for l in linked_prs) else 'fail'">
                Linked pull requests
                <ul class="todo">
                    <t t-foreach="linked_prs" t-as="linked">
                        <li t-att-class="'ok' if linked._ready else 'fail'">
                            <a t-att-href="linked.url" t-field="linked.display_name"/>
                        </li>
                    </t>
                </ul>
            </li>
        </ul>
        </div>
    </template>

    <template id="view_pull_request">
        <t t-call="website.layout">
            <div id="wrap"><div class="container-fluid">
                <t t-call="runbot_merge.alerts"/>
                <h1>
                    <a t-att-href="pr.github_url" t-field="pr.display_name">
                    </a>
                    <a t-attf-href="/web#view_type=form&amp;model=runbot_merge.pull_requests&amp;id={{pr.id}}"
                        class="btn btn-sm btn-secondary align-top float-right"
                        groups="base.group_user">View in backend</a>
                </h1>
                <h6>Created by <span t-field="pr.author.display_name"/></h6>
                <t t-set="tmpl">
                    <t t-if="pr.state in ('merged', 'closed', 'error')"><t t-esc="pr.state"/></t>
                    <t t-elif="pr.staging_id">staging</t>
                    <t t-else="">open</t>
                </t>
                <t t-call="runbot_merge.view_pull_request_info_{{tmpl.strip()}}"/>
                <t t-set="target_cls" t-value="None if pr.target.active else 'text-muted bg-warning'"/>
                <dl class="runbot-merge-fields">
                    <dt>label</dt>
                    <dd><span t-field="pr.label"/></dd>
                    <dt>head</dt>
                    <dd><a t-attf-href="{{pr.github_url}}/commits/{{pr.head}}"><span t-field="pr.head"/></a></dd>
                    <dt t-att-class="target_cls">target</dt>
                    <dd t-att-class="target_cls"><span t-field="pr.target"/></dd>
                </dl>
                <p t-field="pr.message"/>
            </div></div>
        </t>
    </template>
</odoo>