{% extends "base.html" %}
|
|
{% load compress static hc_extras %}
|
|
|
|
{% block title %}Project Settings - {{ project }}{% endblock %}
|
|
|
|
|
|
{% block content %}
|
|
{% with project.transfer_request as transfer_request %}
|
|
<div class="row">
|
|
<div class="col-sm-9 col-md-6">
|
|
{% for message in messages %}
|
|
<p class="alert alert-{{ message.tags }}">{{ message }}</p>
|
|
{% endfor %}
|
|
|
|
{% if transfer_request and transfer_request.user == request.user %}
|
|
{% with can_accept=transfer_request.can_accept %}
|
|
<div id="transfer-request" class="panel">
|
|
<div class="panel-body settings-block">
|
|
<h2>Ownership Transfer Request</h2>
|
|
<p>
|
|
<strong>{{ project.owner.email }}</strong> would like to transfer
|
|
the ownership of this project to you.
|
|
</p>
|
|
|
|
{% if not can_accept %}
|
|
{% with num_checks=project.num_checks num_available=request.profile.num_checks_available %}
|
|
<p>
|
|
This project has
|
|
<strong>{{ num_checks }} check{{ num_checks|pluralize}}</strong>,
|
|
but your account only has space for
|
|
<strong>{{ num_available }} additional check{{ num_available|pluralize }}</strong>.
|
|
To accept the transfer, please
|
|
<a href="{% url 'hc-billing' %}">upgrade your account first!</a>
|
|
</p>
|
|
{% endwith%}
|
|
{% endif %}
|
|
|
|
<div class="pull-right">
|
|
<form method="post">
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
name="reject_transfer"
|
|
class="btn btn-default">Reject</button>
|
|
<button
|
|
type="submit"
|
|
name="accept_transfer"
|
|
{% if not can_accept %}disabled{% endif %}
|
|
class="btn btn-primary">Accept</button>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
{% endwith %}
|
|
{% endif %}
|
|
|
|
<div class="panel panel-{{ project_name_status|default:'default' }}">
|
|
<div class="panel-body settings-block">
|
|
<h2>Project Name</h2>
|
|
{{ project }}
|
|
{% if rw %}
|
|
<a
|
|
href="#"
|
|
class="btn btn-default pull-right"
|
|
data-toggle="modal"
|
|
data-target="#set-project-name-modal">Change Project Name</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if project_name_updated %}
|
|
<div class="panel-footer">
|
|
Project name updated
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="panel panel-{{ api_status|default:'default' }}">
|
|
<div class="panel-body settings-block">
|
|
<h2>API Access</h2>
|
|
{% if project.api_key %}
|
|
{% if show_api_keys %}
|
|
<p>
|
|
API key: <br />
|
|
<pre>{{ project.api_key }}</pre>
|
|
</p>
|
|
{% if project.api_key_readonly %}
|
|
<p>
|
|
API key (read-only): <br />
|
|
<pre>{{ project.api_key_readonly }}</pre>
|
|
</p>
|
|
<p>Related links:</p>
|
|
<ul>
|
|
<li><a href="{% url 'hc-serve-doc' 'api' %}">API documentation</a></li>
|
|
{% if enable_prometheus %}
|
|
<li>
|
|
<a href="{% url 'hc-metrics' project.code project.api_key_readonly %}">Prometheus metrics endpoint</a>
|
|
</li>
|
|
{% endif %}
|
|
<li>
|
|
<a href="{{ project.dashboard_url }}">Read-only dashboard</a>
|
|
(<a href="https://github.com/healthchecks/dashboard/#security">security considerations</a>)
|
|
</li>
|
|
</ul>
|
|
{% endif %}
|
|
<button
|
|
data-toggle="modal"
|
|
data-target="#revoke-api-key-modal"
|
|
class="btn btn-danger pull-right">Revoke</button>
|
|
|
|
{% else %}
|
|
<form method="post">
|
|
<span class="ic-ok"></span>
|
|
API access is enabled.
|
|
{% csrf_token %}
|
|
|
|
{% if rw %}
|
|
<button
|
|
type="submit"
|
|
name="show_api_keys"
|
|
class="btn btn-default pull-right">Show API Keys</button>
|
|
{% endif %}
|
|
</form>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="ic-cancel"></span>
|
|
API access is disabled.
|
|
<form method="post">
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
name="create_api_keys"
|
|
class="btn btn-default pull-right">Create API Keys</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if api_keys_created %}
|
|
<div class="panel-footer">
|
|
API keys created
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if api_keys_revoked %}
|
|
<div class="panel-footer">
|
|
API keys revoked
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% with invite_suggestions=project.invite_suggestions %}
|
|
<div class="panel panel-{{ team_status|default:'default' }}">
|
|
<div class="panel-body settings-block">
|
|
<h2>Team Access</h2>
|
|
{% if project.team.exists or invite_suggestions %}
|
|
<table id="team-table" class="table">
|
|
<tr>
|
|
<th>Email</th>
|
|
<th>Role</th>
|
|
<th></th>
|
|
</tr>
|
|
<tr>
|
|
<td class="email">{{ project.owner.email }}</td>
|
|
<td>Owner</td>
|
|
<td></td>
|
|
</tr>
|
|
{% for m in project.member_set.all %}
|
|
<tr>
|
|
<td class="email">{{ m.user.email }}</td>
|
|
<td>
|
|
{% if m.rw %}
|
|
Member
|
|
{% else %}
|
|
Read-only
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if is_owner %}
|
|
<a
|
|
href="#"
|
|
data-email="{{ m.user.email }}"
|
|
class="pull-right member-remove">Remove</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
|
|
{% if is_owner and invite_suggestions %}
|
|
<tr id="suggestions-row">
|
|
<td colspan="3">
|
|
Add Users from Other Teams
|
|
</td>
|
|
</tr>
|
|
|
|
{% for user in invite_suggestions %}
|
|
<tr class="invite-suggestion">
|
|
<td>{{ user.email }} </td>
|
|
<td></td>
|
|
<td>
|
|
<a
|
|
href="#"
|
|
data-email="{{ user.email }}"
|
|
class="pull-right add-to-team">Add to Team</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</table>
|
|
{% else %}
|
|
<p>
|
|
<strong>Invite team members to your project.</strong>
|
|
Share access to your checks and configured integrations
|
|
without having to share login details.
|
|
</p>
|
|
{% endif %}
|
|
|
|
<br />
|
|
|
|
{% if is_owner %}
|
|
{% if project.can_invite_new_users %}
|
|
<a
|
|
href="#"
|
|
class="btn btn-primary pull-right"
|
|
data-toggle="modal"
|
|
data-target="#invite-team-member-modal">Invite a Team Member</a>
|
|
{% else %}
|
|
<div class="alert alert-info">
|
|
<strong>Team size limit reached.</strong>
|
|
To invite new members by email, please
|
|
<a href="{% url 'hc-pricing' %}">upgrade your account!</a>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
{% endwith %}
|
|
|
|
{% if team_member_invited %}
|
|
<div class="panel-footer">
|
|
{{ team_member_invited }} invited to team
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if team_member_duplicate %}
|
|
<div class="panel-footer">
|
|
{{ team_member_duplicate }} is already a member
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if team_member_removed %}
|
|
<div class="panel-footer">
|
|
{{ team_member_removed }} removed from team
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if is_owner %}
|
|
<div class="panel panel-{{ transfer_status|default:'default' }}"">
|
|
<div class="panel-body settings-block">
|
|
<h2>Transfer Ownership</h2>
|
|
|
|
{% if transfer_request %}
|
|
<form method="post">
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
name="cancel_transfer"
|
|
class="btn btn-default pull-right">Cancel Transfer</button>
|
|
</form>
|
|
|
|
Transfer initiated, awaiting confirmation from
|
|
<strong>{{ transfer_request.user.email }}</strong>.
|
|
|
|
{% else %}
|
|
<a href="#"
|
|
class="btn btn-default pull-right"
|
|
data-toggle="modal"
|
|
data-target="#transfer-modal">Transfer Project…</a>
|
|
Transfer this project to a team member.
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if transfer_initiated %}
|
|
<div class="panel-footer">
|
|
Transfer initiated!
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if transfer_cancelled %}
|
|
<div class="panel-footer">
|
|
Transfer cancelled!
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if is_owner %}
|
|
<div class="panel panel-default">
|
|
<div class="panel-body settings-block">
|
|
{% csrf_token %}
|
|
<h2>Remove Project</h2>
|
|
<a href="#"
|
|
id="remove-project"
|
|
class="btn btn-default pull-right"
|
|
data-toggle="modal"
|
|
data-target="#remove-project-modal">Remove Project</a>
|
|
This will permanently remove project {{ project }}.
|
|
<form action="{% url 'hc-remove-project' project.code %}" method="post">
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="revoke-api-key-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form id="revoke-api-key-form" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Revoke API Keys?</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>You are about to revoke your current API keys.</p>
|
|
<p>Afterwards, you can create new API keys, but there will
|
|
be <strong>no way of getting the current API
|
|
keys back</strong>.
|
|
</p>
|
|
<p>Are you sure?</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
type="submit"
|
|
name="revoke_api_keys"
|
|
class="btn btn-danger">Revoke API Keys</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="remove-team-member-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form id="remove-team-member-form" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Remove Team Member</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>You are about to remove <strong id="rtm-email"></strong> from the project.</p>
|
|
<p>Are you sure?</p>
|
|
<input
|
|
type="hidden"
|
|
name="email"
|
|
id="remove-team-member-email" />
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
type="submit"
|
|
name="remove_team_member"
|
|
class="btn btn-danger">Remove Member from Project</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="invite-team-member-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form method="post" class="form-horizontal">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="invite_team_member" value="1" />
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Invite a Team Member</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<ul>
|
|
<li>Team Members can create and manage Checks and Integrations</li>
|
|
<li>Only the project owner (you) can view and edit billing settings</li>
|
|
</ul>
|
|
<br />
|
|
<div class="form-group">
|
|
<label for="itm-email" class="col-sm-3 control-label">Email</label>
|
|
<div class="col-sm-8">
|
|
<input
|
|
type="email"
|
|
class="form-control"
|
|
id="itm-email"
|
|
name="email"
|
|
maxlength="254"
|
|
placeholder="[email protected]">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">Access Level</label>
|
|
|
|
<div class="col-sm-8">
|
|
<label class="radio-container">
|
|
<input
|
|
type="radio"
|
|
name="rw"
|
|
value="1"
|
|
checked>
|
|
<span class="radiomark"></span>
|
|
Team Member
|
|
</label>
|
|
<label class="radio-container">
|
|
<input
|
|
type="radio"
|
|
name="rw"
|
|
value="">
|
|
<span class="radiomark"></span>
|
|
Read-only
|
|
<span class="help-block">
|
|
Cannot modify checks or integrations.
|
|
Cannot access project's API keys.
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
type="submit"
|
|
name="invite_team_member"
|
|
class="btn btn-primary">Send Invite</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="set-project-name-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form method="post" class="form-horizontal">
|
|
{% csrf_token %}
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Change Project Name</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<label for="project-name" class="col-sm-4 control-label">Project Name</label>
|
|
<div class="col-sm-7">
|
|
<input
|
|
type="text"
|
|
class="form-control"
|
|
id="project-name"
|
|
name="name"
|
|
maxlength="60"
|
|
value="{{ project }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
type="submit"
|
|
name="set_project_name"
|
|
class="btn btn-primary">Set Project Name</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="remove-project-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form method="post" action="{% url 'hc-remove-project' project.code %}">
|
|
{% csrf_token %}
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Remove "{{ project }}"?</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Danger zone! You are about to permanently remove
|
|
project <strong>{{ project }}</strong> and all
|
|
of its associated checks and integrations. Are you sure?
|
|
</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
type="submit"
|
|
class="btn btn-danger">Remove Project</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% if not transfer_request %}
|
|
<div id="transfer-modal" class="modal">
|
|
<div class="modal-dialog">
|
|
<form
|
|
class="form-horizontal"
|
|
method="post">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="transfer_project" value="1" />
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4>Transfer Ownership</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
|
|
{% if project.team %}
|
|
<div class="form-group">
|
|
<label for="update-name-input" class="col-sm-4 control-label">
|
|
Choose owner
|
|
</label>
|
|
<div class="col-sm-7">
|
|
<select
|
|
id="new-owner"
|
|
name="email"
|
|
title="Select..."
|
|
class="form-control selectpicker">
|
|
{% for user in project.team %}
|
|
<option>{{ user.email }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<p>
|
|
This project currently has no team members.
|
|
To transfer the ownership of this project, please start by
|
|
inviting the new owner as a team member.
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
<button
|
|
id="transfer-confirm"
|
|
disabled
|
|
type="submit"
|
|
class="btn btn-primary">Initiate Transfer</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% endwith %}
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
{% compress js %}
|
|
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
|
<script src="{% static 'js/bootstrap-select.min.js' %}"></script>
|
|
<script src="{% static 'js/project.js' %}"></script>
|
|
{% endcompress %}
|
|
{% endblock %}
|