Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions readthedocsext/theme/static/readthedocsext/theme/js/site.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

22 changes: 19 additions & 3 deletions readthedocsext/theme/templates/builds/build_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{% endblock content-header %}

{% block content %}
<div data-bind="using: BuildDetailView({}, '{% url "build-detail" build.id %}', '{% url "projects-builds-notifications-list" build.project.slug build.id %}')">
<div data-bind="using: BuildDetailView({}, '{% url "build-detail" build.id %}', '{% url "projects-builds-notifications-list" build.project.slug build.id %}', {{ files_changed_diff|yesno:"true,false" }})">

{% block build_detail_metadata %}
<div class="ui top attached segment">
Expand Down Expand Up @@ -107,7 +107,15 @@
{% endblock build_detail_metadata %}

<div class="ui attached stackable menu">
<a class="active item">
{% if files_changed_diff %}
<a class="active item"
data-bind="click: show_files_changed_tab, css: {active: show_files_changed()}">
<i class="fa-duotone fa-code-compare icon"></i>
{% trans "Files changed" %}
</a>
{% endif %}
<a class="item{% if not files_changed_diff %} active{% endif %}"
data-bind="click: show_output_tab, css: {active: !show_files_changed()}">
<i class="fa-duotone fa-terminal icon"></i>
{% trans "Output" %}
</a>
Expand Down Expand Up @@ -219,7 +227,8 @@
</div>
{% endblock build_detail_notifications %}

<div class="ui inverted bottom attached horizontally scrolling segment transition slide">
<div class="ui inverted bottom attached horizontally scrolling segment transition slide{% if files_changed_diff %} ko hidden{% endif %}"
data-bind="css: { hidden: show_files_changed() }">

{% comment %}
This is a loading placeholder. The extra element is to fill out the
Expand Down Expand Up @@ -282,5 +291,12 @@
</div>
{% endif %}

{% if files_changed_diff %}
<div class="ui bottom attached segment ko"
data-bind="css: { hidden: !show_files_changed() }">
{% include "builds/partials/build_files_changed.html" %}
</div>
{% endif %}

</div>
{% endblock content %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
{% comment "rst" %}

Build files changed
===================

``builds/partials/build_files_changed.html``

Renders the contents of the "Files changed" tab on the build detail page.

It shows the file tree diff for a build as a single, flat list of the
documentation pages that were added, modified, or deleted compared to a
base. Pull request builds are compared against the base version, while
normal version builds are compared against the version's previous build.

Pull request builds also show a small pull request info card.

Template parameters
-------------------

.. describe:: build

The build instance the diff belongs to.

.. describe:: files_changed_diff

A ``FileTreeDiff`` instance with the added, modified, and deleted files.

{% endcomment %}

{% load blocktrans trans from i18n %}

{% if build.is_external %}
{% comment %}
The state badge is a direct child of the header on purpose: Fomantic only
vertically centers a label via `.ui.header > .ui.label`. Wrapping the
content -- for example, to add a header icon -- breaks that centering.
{% endcomment %}
<div class="ui segment">
<div class="ui small header">
<a href="{{ build.version.vcs_url }}" target="_blank" rel="noopener">
{{ build.external_version_name|lower|capfirst }} #{{ build.get_version_name }}
</a>
{% if build.version.state == "open" %}
<span class="ui mini horizontal green label">{% trans "Open" %}</span>
{% elif build.version.state == "closed" %}
<span class="ui mini horizontal grey label">{% trans "Closed" %}</span>
{% endif %}
</div>
</div>
{% endif %}

<p class="ui grey text">
{% if build.is_external %}
{% blocktrans trimmed with base_version=files_changed_diff.base_version.verbose_name %}
Comparing this pull request against <code>{{ base_version }}</code>.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed with base_build_id=files_changed_diff.base_version_build.pk %}
Comparing this build against the previous build (#{{ base_build_id }}) of this version.
{% endblocktrans %}
{% endif %}
</p>

{% if files_changed_diff.outdated %}
<div class="ui warning message">
<i class="fa-duotone fa-triangle-exclamation icon"></i>
{% trans "A newer build exists for this version, so this comparison may be out of date." %}
</div>
{% endif %}

{% if files_changed_diff.files %}

<div class="ui segments">
<div class="ui secondary segment">
{% blocktrans trimmed count counter=files_changed_diff.files|length %}
<strong>{{ counter }}</strong> file changed
{% plural %}
<strong>{{ counter }}</strong> files changed
{% endblocktrans %}
{% if files_changed_diff.added %}
·
{% blocktrans trimmed with counter=files_changed_diff.added|length %}
<strong>{{ counter }}</strong> added
{% endblocktrans %}
{% endif %}
{% if files_changed_diff.modified %}
·
{% blocktrans trimmed with counter=files_changed_diff.modified|length %}
<strong>{{ counter }}</strong> modified
{% endblocktrans %}
{% endif %}
{% if files_changed_diff.deleted %}
·
{% blocktrans trimmed with counter=files_changed_diff.deleted|length %}
<strong>{{ counter }}</strong> deleted
{% endblocktrans %}
{% endif %}
</div>

<div class="ui segment">
<div class="ui divided relaxed list">
{% for file in files_changed_diff.files %}
<div class="item">
{% if file.status == "added" %}
<i class="green fa-duotone fa-square-plus icon"></i>
{% elif file.status == "deleted" %}
<i class="red fa-duotone fa-square-minus icon"></i>
{% else %}
<i class="orange fa-duotone fa-pen-to-square icon"></i>
{% endif %}
<div class="content">
{% if file.status == "deleted" %}
<code>{{ file.path }}</code>
{% else %}
<a href="{{ file.url }}" target="_blank" rel="noopener">
<code>{{ file.path }}</code>
</a>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
</div>

{% else %}

<div class="ui basic center aligned segment">
<i class="fa-duotone fa-circle-check large green icon"></i>
<p>{% trans "No documentation files changed in this build." %}</p>
</div>

{% endif %}
23 changes: 22 additions & 1 deletion src/js/build/detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,12 @@ class BuildCommand {
export class BuildDetailView {
static view_name = "BuildDetailView";

constructor(build = {}, url_api_build, url_api_notifications) {
constructor(
build = {},
url_api_build,
url_api_notifications,
show_files_changed = false,
) {
/** @type {number} The build pk/id to fetch */
this.id = build.id;
/** @type {string} APIv2 build detail API URL */
Expand Down Expand Up @@ -402,6 +407,12 @@ export class BuildDetailView {
/** @observable {Boolean} Show debug/info commands */
this.show_debug = ko.observable(false);

/* Files changed */
/** @observable {Boolean} Show the files changed tab instead of the build
* command output. Defaults to the files changed tab when a diff is
* available for this build. */
this.show_files_changed = ko.observable(show_files_changed);

/** @observable {Boolean} Are we still polling the API? */
this.is_polling = ko.observable(true);
this.is_polling.subscribe((is_polling) => {
Expand Down Expand Up @@ -605,6 +616,16 @@ export class BuildDetailView {
this.show_debug(!show_debug);
}

/** Switch the build detail view to the build command output tab */
show_output_tab() {
this.show_files_changed(false);
}

/** Switch the build detail view to the files changed tab */
show_files_changed_tab() {
this.show_files_changed(true);
}

/** Update all attributes and observables that depend on build state */
update_state(state) {
// Is build in one of the finished states?
Expand Down