Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR-491 - merge #90

Open
wants to merge 20 commits into
base: release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ test: py-venv-check
coverage:
pytest --cov=ambuda --cov-report=html test/

coverage-report: coverage
coverage report --fail-under=80

# Generate Ambuda's technical documentation.
# After the command completes, open "docs/_build/index.html".
docs: py-venv-check
Expand Down Expand Up @@ -275,6 +278,8 @@ babel-update: py-venv-check
babel-compile: py-venv-check
pybabel compile -d ambuda/translations

# Clean up
# ===============================================
clean:
@rm -rf deploy/data/
@rm -rf ambuda/translations/*
44 changes: 44 additions & 0 deletions ambuda/templates/proofing/projects/confirm_changes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{% extends 'proofing/base.html' %}
{% from "macros/forms.html" import field %}
{% import "macros/proofing.html" as m %}

{% block title %} Search and Replace | {{ project.title }}{% endblock %}

{% block content %}

{{ m.project_header_nested('Review and Confirm Changes', project) }}
{{ m.project_nav(project=project, active='edit') }}

<div class="prose">
<h1>Confirm Changes</h1>
{% macro sp(s, p, n) %}{% if n == 1 %}{{ s }}{% else %}{{ p }}{% endif %}{% endmacro %}
<p>Please carefully review and confirm the changes you selected:</p>
<form method="POST" action="{{ url_for('proofing.project.confirm_changes', slug=project.slug) }}" class="bg-slate-100 p-4 my-4">
{{ form.csrf_token }}
<input type="hidden" name="query" value="{{ query }}">
<input type="hidden" name="replace" value="{{ replace }}">

{% set match_counts = results|map(attribute='matches')|map('length')|list %}
{% set nr = match_counts|sum %}
<p>Confirm changes on {{ nr }} {{ sp("match", "matches", nr) }} that {{ sp("contains", "contain", nr) }} <span style="color: red;"><kbd>{{ query }}</kbd></span> to be replaced by <span style="color: green;"><kbd>{{ replace }}</kbd></span>.</p>

{% for result in results %}
{% set page = result.page %}
{% set page_url = url_for("proofing.page.edit", project_slug=project.slug, page_slug=page.slug) %}
{% set matches = result.matches %}
{% for match in matches %}
<div class="match" style="background-color: rgb(243, 239, 239);">
<p>Page <a href="{{ page_url }}">{{ project.title }}/{{ page.slug }}:</a> Line {{ match.line_num }}</p>
<label for="match{{ page.slug }}-{{ match.line_num }}">{{ match.query }}</label>
<input type="hidden" name="match{{ page.slug }}-{{ match.line_num }}-query" value="{{ match.query }}">
<br>
<label for="match{{ page.slug }}-{{ match.line_num }}-replace" style="color: rgb(97, 86, 66); background-color: rgb(219, 215, 215);"> {{ match.replace }} </label>
<input type="hidden" name="match{{ page.slug }}-{{ match.line_num }}-replace" value="{{ match.replace }}">
</div>
{% endfor %}
{% endfor %}
<button class="btn btn-submit" type="submit" name="cancel" value="cancel">Cancel</button>
<button class="btn btn-submit" type="submit" name="confirm" value="confirm">Confirm</button>
</form>
</div>
{% endblock %}
111 changes: 84 additions & 27 deletions ambuda/templates/proofing/projects/replace.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,95 @@
{{ m.project_nav(project=project, active='edit') }}

<div class="prose">
<p>Use this simple search and replace form to make edits across this project.</p>
<h1>Replace</h1>
<p>Use this simple search and replace form to make edits across this project. The search supports regular expressions.</p>
<form method="POST" class="bg-slate-100 p-4 my-4">

{{ field(form.query) }}
{{ field(form.replace) }}
<input class="btn btn-submit" type="submit" name="search" value="Project-wide Search & Replace">
</form>
</div>

<form method="GET" class="bg-slate-100 p-4 my-4">
{{ field(form.query) }}
{{ field(form.replace) }}
<input class="btn btn-submit" type="submit" value="Project-wide Search & Replace">
</form>

{% if query %}
{% if results %}
<div class="prose">
<h1>Matches</h1>
{% macro sp(s, p, n) %}{% if n == 1 %}{{ s }}{% else %}{{ p }}{% endif %}{% endmacro %}
<form method="POST" action="{{ url_for('proofing.project.submit_changes', slug=project.slug) }}" class="bg-slate-100 p-4 my-4">
{{ submit_changes_form.csrf_token }}
<input type="hidden" name="query" value="{{ query }}">
<input type="hidden" name="replace" value="{{ replace }}">

{% macro sp(s, p, n) %}{% if n == 1 %}{{ s }}{% else %}{{ p }}{% endif %}{% endmacro %}

{% set nr = results|length %}
<p>Found {{ nr }} {{ sp("page", "pages", nr) }} that {{ sp("contains", "contain", nr) }} <kbd>{{ query }}</kbd>.</p>

<ul>
{% for page in results %}
{% set page_url = url_for("proofing.page.edit", project_slug=project.slug, page_slug=page.slug) %}
<li>
<a href="{{ page_url }}">{{ project.title }}/{{ page.slug }}</a>
<div class="p-2 border-l my-2">
{% for match in page.matches %}
<pre class="p-0.5">{{ match.query }}</pre>
<pre class="p-0.5">{{ match.update }}</pre>
{%- endfor %}
{% set nr = results|length %}
<p>Found {{ nr }} {{ sp("page", "pages", nr) }} that {{ sp("contains", "contain", nr) }} <kbd>{{ query }}</kbd>.</p>
<ul>
<div class="match">
<input type="checkbox" name="select-all" id="select-all">
<label for="select-all">Select all in this page </label>
</div>
</li>
{% endfor %}
</ul>

{% for page in results %}
{% set page_url = url_for("proofing.page.edit", project_slug=project.slug, page_slug=page.slug) %}
<li>
<a href="{{ page_url }}">{{ project.title }}/{{ page.slug }}</a>
<div class="p-2 border-l my-2">
{% for match in page.matches %}
<div class="match" style="background-color: rgb(243, 239, 239);">
<input type="checkbox" name="match{{ page.slug }}-{{ match.line_num }}" id="match{{ page.slug }}-{{ match.line_num }}" value="selected">
<p>Page <a href="{{ page_url }}">{{ project.title }}/{{ page.slug }}:</a> Line {{ match.line_num }}</p>
<label for="match{{ page.slug }}-{{ match.line_num }}">{{ match.query|safe }}</label>
<br>
<label for="match{{ page.slug }}-{{ match.line_num }}-replace" style="color: rgb(97, 86, 66); background-color: rgb(219, 215, 215);"> {{ match.replace|safe }} </label>
<input type="hidden" name="match{{ page.slug }}-{{ match.line_num }}-replace" id="match{{ page.slug }}-{{ match.line_num }}-replace" value="{{ match.replace }}">
</div>
<br>
{% endfor %}
</div>
</li>
{% endfor %}
{% if submit_changes_form %}
{{ submit_changes_form.submit(class="btn btn-submit") }}
{% else %}
<input class="btn btn-submit" type="submit" name="submit" value="Submit Changes">
{% endif %}
</form>
</ul>
<script>
(function() {
// Get references to the "select-all" checkbox and all the other checkboxes
const checkAll = document.querySelector("#select-all");
const checkboxes = document.querySelectorAll('input[type="checkbox"][name^="match"]');

// Function to update the visibility of the replaceField element
function updateReplaceFieldVisibility(checkbox) {
const replaceField = document.querySelector(`#${checkbox.id}-replace`);
if (checkbox.checked) {
replaceField.style.display = "";
} else {
replaceField.style.display = "none";
}
}

// Add a change event listener to the "select-all" checkbox
checkAll.addEventListener("change", function(event) {
// If the "select-all" checkbox is checked, check all the other checkboxes
// and update the replaceField visibility
checkboxes.forEach(function(checkbox) {
checkbox.checked = event.target.checked;
updateReplaceFieldVisibility(checkbox);
});
});

// Add change event listeners to each individual checkbox
checkboxes.forEach(function(checkbox) {
checkbox.addEventListener("change", function(event) {
updateReplaceFieldVisibility(event.target);

// Update the state of the 'select-all' checkbox
checkAll.checked = Array.from(checkboxes).every(checkbox => checkbox.checked);
});
});
})();
</script>
</div>
{% endif %}
{% endblock %}
Loading