Browse Source

Add a "Create a Copy" function for cloning checks Fixes #288

pull/307/head
Pēteris Caune 5 years ago
parent
commit
488ab2cce7
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
  1. 1
      CHANGELOG.md
  2. 18
      hc/front/tests/test_copy.py
  3. 1
      hc/front/urls.py
  4. 22
      hc/front/views.py
  5. 22
      static/css/details.css
  6. 32
      templates/front/copy_modal.html
  7. 32
      templates/front/details.html
  8. 6
      templates/front/remove_check_modal.html

1
CHANGELOG.md

@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
- Autofocus the email field in the signup form, and submit on enter key
- Add support for OpsGenie EU region (#294)
- Update OpsGenie logo and setup illustrations
- Add a "Create a Copy" function for cloning checks (#288)
### Bug Fixes
- Prevent double-clicking the submit button in signup form

18
hc/front/tests/test_copy.py

@ -0,0 +1,18 @@
from hc.api.models import Channel, Check
from hc.test import BaseTestCase
class CopyCheckTestCase(BaseTestCase):
def setUp(self):
super(CopyCheckTestCase, self).setUp()
self.check = Check(project=self.project)
self.check.name = "Foo"
self.check.save()
self.copy_url = "/checks/%s/copy/" % self.check.code
def test_it_works(self):
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.copy_url, follow=True)
self.assertContains(r, "This is a brand new check")
self.assertContains(r, "Foo (copy)")

1
hc/front/urls.py

@ -13,6 +13,7 @@ check_urls = [
path("status/", views.status_single, name="hc-status-single"),
path("last_ping/", views.ping_details, name="hc-last-ping"),
path("transfer/", views.transfer, name="hc-transfer"),
path("copy/", views.copy, name="hc-copy"),
path(
"channels/<uuid:channel_code>/enabled",
views.switch_channel,

22
hc/front/views.py

@ -483,6 +483,7 @@ def details(request, code):
"timezones": pytz.all_timezones,
"downtimes": check.downtimes(months=3),
"is_new": "new" in request.GET,
"is_copied": "copied" in request.GET,
}
return render(request, "front/details.html", ctx)
@ -513,6 +514,27 @@ def transfer(request, code):
return render(request, "front/transfer_modal.html", ctx)
@require_POST
@login_required
def copy(request, code):
check = _get_check_for_user(request, code)
copied = Check(project=check.project)
copied.name = check.name + " (copy)"
copied.desc, copied.tags = check.desc, check.tags
copied.subject = check.subject
copied.kind = check.kind
copied.timeout, copied.grace = check.timeout, check.grace
copied.schedule, copied.tz = check.schedule, check.tz
copied.save()
copied.channel_set.add(*check.channel_set.all())
url = reverse("hc-details", args=[copied.code])
return redirect(url + "?copied")
@login_required
def status_single(request, code):
check = _get_check_for_user(request, code)

22
static/css/details.css

@ -103,3 +103,25 @@
text-align: center;
padding: 32px;
}
ul.checkmarks {
padding-left: 20px;
list-style: none;
color: #117a3f;
}
ul.checkmarks li:before {
content: '✔ ';
}
ul.crosses {
padding-left: 20px;
list-style: none;
color: #aa413e;
}
ul.crosses li:before {
content: '✘ ';
}

32
templates/front/copy_modal.html

@ -0,0 +1,32 @@
<div id="copy-modal" class="modal">
<div class="modal-dialog">
<form action="{% url 'hc-copy' check.code %}" method="post">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4>Create a Copy of This Check</h4>
</div>
<div class="modal-body">
<p>You are about to <strong>create a new check based on this
check's configuration</strong>. The following items will
get copied:</p>
<ul class="checkmarks">
<li>Name, tags and description</li>
<li>Schedule</li>
<li>Assigned notification methods</li>
</ul>
<p>The following items <em>will not</em> be copied:</p>
<ul class="crosses">
<li>Its URL (a new URL will be generated)</li>
<li>The log of already received pings</li>
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Create a Copy</button>
</div>
</div>
</form>
</div>
</div>

32
templates/front/details.html

@ -11,12 +11,23 @@
<div class="col-sm-12">
<p id="new-check-alert" class="alert alert-success">
<strong>Your new check is ready!</strong>
You can now
<a data-target="edit-name" href="#" >give it a name</a>
or
You can now
<a data-target="edit-name" href="#" >give it a name</a>
or
<a data-target="edit-timeout" href="#" >set its schedule</a>.
</p>
</div>
</div>
{% endif %}
{% if is_copied %}
<div class="col-sm-12">
<p id="new-check-alert" class="alert alert-success">
<strong>Copy created!</strong>
This is a brand new check, with details copied over from your existing check.
You might now want to
<a data-target="edit-name" href="#">update its name and tags</a>.
</p>
</div>
{% endif %}
{% if messages %}
@ -196,15 +207,21 @@
<div class="details-block">
<h2>Danger Zone</h2>
<p>Transfer to a different project, or permanently remove this check.</p>
<p>Copy, Transfer, or permanently remove this check.</p>
<div class="text-right">
<button
id="copy-btn"
data-toggle="modal"
data-target="#copy-modal"
class="btn btn-sm btn-default">Create a Copy&hellip;</button>
<button
id="transfer-btn"
data-toggle="modal"
data-target="#transfer-modal"
data-url="{% url 'hc-transfer' check.code %}"
class="btn btn-sm btn-default">Transfer to Another Project&hellip;</button>
&nbsp;
<button
id="details-remove-check"
data-toggle="modal"
@ -223,13 +240,13 @@
<label class="btn btn-default btn-xs" data-format="UTC">
<input type="radio" name="date-format">
UTC
</label>
</label>
{% if check.kind == "cron" and check.tz != "UTC" %}
<label class="btn btn-default btn-xs" data-format="{{ check.tz }}">
<input type="radio" name="date-format">
{{ check.tz }}
</label>
</label>
{% endif %}
<label class="btn btn-default btn-xs active" data-format="local">
@ -263,6 +280,7 @@
{% include "front/show_usage_modal.html" %}
{% include "front/remove_check_modal.html" %}
{% include "front/email_settings_modal.html" %}
{% include "front/copy_modal.html" %}
{% endblock %}

6
templates/front/remove_check_modal.html

@ -1,10 +1,6 @@
<div id="remove-check-modal" class="modal">
<div class="modal-dialog">
<form
id="remove-check-form"
{% if check %}action="{% url 'hc-remove-check' check.code %}"{% endif %}
method="post">
<form action="{% url 'hc-remove-check' check.code %}" method="post">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">

Loading…
Cancel
Save