Skip to content

Commit

Permalink
Add a "Create a Copy" function for cloning checks Fixes #288
Browse files Browse the repository at this point in the history
  • Loading branch information
cuu508 committed Oct 18, 2019
1 parent a5827c6 commit 488ab2c
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions 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 change: 1 addition & 0 deletions hc/front/urls.py
Expand Up @@ -13,6 +13,7 @@
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,
Expand Down
22 changes: 22 additions & 0 deletions hc/front/views.py
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
22 changes: 22 additions & 0 deletions static/css/details.css
Expand Up @@ -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 changes: 32 additions & 0 deletions 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 changes: 25 additions & 7 deletions templates/front/details.html
Expand Up @@ -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 %}
Expand Down Expand Up @@ -196,15 +207,21 @@ <h2>Notification Methods</h2>

<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"
Expand All @@ -223,13 +240,13 @@ <h2>
<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">
Expand Down Expand Up @@ -263,6 +280,7 @@ <h2>
{% include "front/show_usage_modal.html" %}
{% include "front/remove_check_modal.html" %}
{% include "front/email_settings_modal.html" %}
{% include "front/copy_modal.html" %}

{% endblock %}

Expand Down
6 changes: 1 addition & 5 deletions 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">
Expand Down

0 comments on commit 488ab2c

Please sign in to comment.