mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 15:57:23 -04:00
Merge branch 'master' into celery-jobs
Conflicts: app/main/views/sms.py
This commit is contained in:
@@ -155,7 +155,7 @@ def useful_headers_after_request(response):
|
||||
response.headers.add('X-Content-Type-Options', 'nosniff')
|
||||
response.headers.add('X-XSS-Protection', '1; mode=block')
|
||||
response.headers.add('Content-Security-Policy',
|
||||
"default-src 'self' 'unsafe-inline'; font-src 'self' data:;") # noqa
|
||||
"default-src 'self' 'unsafe-inline'; font-src 'self' data:; img-src 'self' data:;") # noqa
|
||||
if 'Cache-Control' in response.headers:
|
||||
del response.headers['Cache-Control']
|
||||
response.headers.add(
|
||||
|
||||
BIN
app/assets/images/tick-white.png
Normal file
BIN
app/assets/images/tick-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 622 B |
BIN
app/assets/images/tick.png
Normal file
BIN
app/assets/images/tick.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 834 B |
BIN
app/assets/images/tick.psd
Normal file
BIN
app/assets/images/tick.psd
Normal file
Binary file not shown.
@@ -3,22 +3,16 @@
|
||||
|
||||
Modules.FileUpload = function() {
|
||||
|
||||
let $field, $button, $filename;
|
||||
let $form;
|
||||
|
||||
this.update = function() {
|
||||
|
||||
$filename.text($field.val().split('\\').pop());
|
||||
|
||||
};
|
||||
this.submit = () => $form.trigger('submit');
|
||||
|
||||
this.start = function(component) {
|
||||
|
||||
$field = $('.file-upload-field', component);
|
||||
$button = $('.file-upload-button', component);
|
||||
$filename = $('.file-upload-filename', component);
|
||||
$form = $(component);
|
||||
|
||||
// Need to put the event on the container, not the input for it to work properly
|
||||
$(component).on('change', '.file-upload-field', this.update);
|
||||
$form.on('change', '.file-upload-field', this.submit);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
$(() => GOVUK.modules.start());
|
||||
|
||||
$(() => new GOVUK.SelectionButtons('.block-label input, .sms-message-option input'));
|
||||
|
||||
$(() => $('.error-message').eq(0).parent('label').next('input').trigger('focus'));
|
||||
|
||||
@@ -66,3 +66,16 @@ a {
|
||||
font-family: monospace;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.inline {
|
||||
|
||||
.block-label {
|
||||
|
||||
@include media(tablet) {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,13 @@
|
||||
|
||||
.banner-with-tick,
|
||||
.banner-default-with-tick {
|
||||
|
||||
@extend %banner;
|
||||
padding: $gutter-half ($gutter + $gutter-half);
|
||||
|
||||
&:before {
|
||||
@include core-24;
|
||||
content: '✔';
|
||||
position: absolute;
|
||||
top: $gutter-half;
|
||||
left: $gutter-half;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
background-image: file-url('tick-white.png');
|
||||
background-size: 19px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: $gutter-half $gutter-half;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.banner-dangerous {
|
||||
@@ -70,13 +64,18 @@
|
||||
|
||||
}
|
||||
|
||||
.banner-info,
|
||||
.banner-important {
|
||||
@extend %banner;
|
||||
background: $white;
|
||||
color: $text-colour;
|
||||
background-image: file-url('icon-important-2x.png');
|
||||
background-size: 34px 34px;
|
||||
background-position: 0 0;
|
||||
background-position: 0 0px;
|
||||
background-repeat: no-repeat;
|
||||
padding: 7px 0 5px 50px;
|
||||
}
|
||||
|
||||
.banner-info {
|
||||
background-image: file-url('icon-information-2x.png');
|
||||
}
|
||||
|
||||
@@ -3,9 +3,15 @@
|
||||
.file-upload {
|
||||
|
||||
&-label {
|
||||
|
||||
@include bold-19;
|
||||
display: block;
|
||||
margin: 0 0 10px 0;
|
||||
|
||||
.error-message {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&-field {
|
||||
@@ -23,7 +29,7 @@
|
||||
}
|
||||
|
||||
&-button {
|
||||
@include button($panel-colour);
|
||||
@include button($button-colour);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -33,6 +39,10 @@
|
||||
padding-left: $gutter-half;
|
||||
}
|
||||
|
||||
&-submit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
&-delete-link {
|
||||
|
||||
line-height: 40px;
|
||||
padding: 0 0 0 5px;
|
||||
padding: 1px 0 0 15px;
|
||||
|
||||
a {
|
||||
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
margin: 40px 0 5px 0;
|
||||
}
|
||||
|
||||
.table-field-headings {
|
||||
th {
|
||||
padding: 0 0 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
%table-field,
|
||||
.table-field {
|
||||
|
||||
@@ -36,6 +42,19 @@
|
||||
|
||||
}
|
||||
|
||||
&-yes,
|
||||
&-no {
|
||||
display: block;
|
||||
text-indent: -999em;
|
||||
background-size: 19px 19px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
|
||||
&-yes {
|
||||
background-image: file-url('tick.png');
|
||||
}
|
||||
|
||||
&-missing {
|
||||
color: $error-colour;
|
||||
font-weight: bold;
|
||||
@@ -77,4 +96,5 @@
|
||||
margin-top: -20px;
|
||||
border-bottom: 1px solid $border-colour;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
36
app/assets/stylesheets/components/yes-no.scss
Normal file
36
app/assets/stylesheets/components/yes-no.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
.yes-no-wrapper {
|
||||
border-bottom: 1px solid $border-colour;
|
||||
margin: 0 0 $gutter 0;
|
||||
}
|
||||
|
||||
.yes-no {
|
||||
|
||||
border-top: 1px solid $border-colour;
|
||||
padding: 10px 0;
|
||||
|
||||
&-label {
|
||||
padding-top: 19px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
&-fields {
|
||||
|
||||
text-align: right;
|
||||
|
||||
.block-label {
|
||||
|
||||
@include media(tablet) {
|
||||
|
||||
margin-bottom: 0;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ $path: '/static/images/';
|
||||
@import 'components/browse-list';
|
||||
@import 'components/email-message';
|
||||
@import 'components/api-key';
|
||||
@import 'components/yes-no';
|
||||
|
||||
@import 'views/job';
|
||||
@import 'views/edit-template';
|
||||
|
||||
@@ -5,5 +5,5 @@ main = Blueprint('main', __name__)
|
||||
from app.main.views import (
|
||||
index, sign_in, sign_out, register, two_factor, verify, sms, add_service,
|
||||
code_not_received, jobs, dashboard, templates, service_settings, forgot_password,
|
||||
new_password, styleguide, user_profile, choose_service, api_keys
|
||||
new_password, styleguide, user_profile, choose_service, api_keys, manage_users
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from flask import url_for
|
||||
from flask import url_for, abort
|
||||
from app import notifications_api_client
|
||||
from notifications_python_client.errors import HTTPError
|
||||
from app.utils import BrowsableItem
|
||||
from notifications_python_client.errors import HTTPError
|
||||
|
||||
|
||||
def insert_new_service(service_name, user_id):
|
||||
@@ -29,7 +29,9 @@ def get_service_by_id(id_):
|
||||
|
||||
def get_service_by_id_or_404(id_):
|
||||
try:
|
||||
return get_service_by_id(id_)
|
||||
return notifications_api_client.get_service(id_)['data']
|
||||
except KeyError:
|
||||
abort(404)
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
abort(404)
|
||||
|
||||
@@ -21,10 +21,10 @@ from app.utils import (
|
||||
)
|
||||
|
||||
|
||||
def email_address():
|
||||
def email_address(label='Email address'):
|
||||
gov_uk_email \
|
||||
= "(^[^@^\\s]+@[^@^\\.^\\s]+(\\.[^@^\\.^\\s]*)*.gov.uk)"
|
||||
return EmailField('Email address', validators=[
|
||||
return EmailField(label, validators=[
|
||||
Length(min=5, max=255),
|
||||
DataRequired(message='Email cannot be empty'),
|
||||
Email(message='Enter a valid email address'),
|
||||
@@ -96,6 +96,10 @@ class RegisterUserForm(Form):
|
||||
password = password()
|
||||
|
||||
|
||||
class InviteUserForm(Form):
|
||||
email_address = email_address('Their email address')
|
||||
|
||||
|
||||
class TwoFactorForm(Form):
|
||||
def __init__(self, validate_code_func, *args, **kwargs):
|
||||
'''
|
||||
|
||||
@@ -34,63 +34,3 @@ def send_email(service_id):
|
||||
@login_required
|
||||
def check_email(service_id):
|
||||
return render_template('views/check-email.html')
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/manage-users")
|
||||
@login_required
|
||||
def manage_users(service_id):
|
||||
users = [
|
||||
{
|
||||
'name': 'Henry Hadlow',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': False,
|
||||
'permission_manage_api_keys': False
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'Pete Herlihy',
|
||||
'permission_send_messages': False,
|
||||
'permission_manage_service': False,
|
||||
'permission_manage_api_keys': False,
|
||||
},
|
||||
{
|
||||
'name': 'Chris Hill-Scott',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': True,
|
||||
'permission_manage_api_keys': True
|
||||
},
|
||||
{
|
||||
'name': 'Martyn Inglis',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': True,
|
||||
'permission_manage_api_keys': True
|
||||
}
|
||||
]
|
||||
invited_users = [
|
||||
{
|
||||
'email_localpart': 'caley.smolska',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': False,
|
||||
'permission_manage_api_keys': False
|
||||
},
|
||||
|
||||
{
|
||||
'email_localpart': 'ash.stephens',
|
||||
'permission_send_messages': False,
|
||||
'permission_manage_service': False,
|
||||
'permission_manage_api_keys': False
|
||||
},
|
||||
{
|
||||
'email_localpart': 'nicholas.staples',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': True,
|
||||
'permission_manage_api_keys': True
|
||||
},
|
||||
{
|
||||
'email_localpart': 'adam.shimali',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': True,
|
||||
'permission_manage_api_keys': True
|
||||
}
|
||||
]
|
||||
return render_template('views/manage-users.html', service_id=service_id, users=users, invited_users=invited_users)
|
||||
|
||||
96
app/main/views/manage_users.py
Normal file
96
app/main/views/manage_users.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from flask import (
|
||||
request,
|
||||
render_template,
|
||||
redirect,
|
||||
abort,
|
||||
url_for,
|
||||
flash
|
||||
)
|
||||
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from app.main import main
|
||||
from app.main.dao import users_dao
|
||||
from app.main.forms import InviteUserForm
|
||||
from app.main.dao.services_dao import get_service_by_id_or_404
|
||||
from app import user_api_client
|
||||
|
||||
fake_users = [
|
||||
{
|
||||
'name': '',
|
||||
'permission_send_messages': True,
|
||||
'permission_manage_service': True,
|
||||
'permission_manage_api_keys': True,
|
||||
'active': True
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/users")
|
||||
@login_required
|
||||
def manage_users(service_id):
|
||||
return render_template(
|
||||
'views/manage-users.html',
|
||||
service_id=service_id,
|
||||
users=fake_users,
|
||||
current_user=current_user,
|
||||
invited_users=[]
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/users/invite", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def invite_user(service_id):
|
||||
|
||||
form = InviteUserForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
flash('Invite sent to {}'.format(form.email_address.data), 'default_with_tick')
|
||||
return redirect(url_for('.manage_users', service_id=service_id))
|
||||
|
||||
return render_template(
|
||||
'views/invite-user.html',
|
||||
user={},
|
||||
service=get_service_by_id_or_404(service_id),
|
||||
service_id=service_id,
|
||||
form=form
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/users/<user_id>", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_user(service_id, user_id):
|
||||
|
||||
if request.method == 'POST':
|
||||
return redirect(url_for('.manage_users', service_id=service_id))
|
||||
|
||||
return render_template(
|
||||
'views/invite-user.html',
|
||||
user=fake_users[int(user_id)],
|
||||
user_id=user_id,
|
||||
service=get_service_by_id_or_404(service_id),
|
||||
service_id=service_id
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/users/<user_id>/delete", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_user(service_id, user_id):
|
||||
|
||||
if request.method == 'POST':
|
||||
return redirect(url_for('.manage_users', service_id=service_id))
|
||||
|
||||
user = fake_users[int(user_id)]
|
||||
|
||||
flash(
|
||||
'Are you sure you want to delete {}’s account?'.format(user.get('name') or user['email_localpart']),
|
||||
'delete'
|
||||
)
|
||||
|
||||
return render_template(
|
||||
'views/invite-user.html',
|
||||
user=user,
|
||||
user_id=user_id,
|
||||
service=get_service_by_id_or_404(service_id),
|
||||
service_id=service_id
|
||||
)
|
||||
@@ -37,11 +37,23 @@ from app.utils import (
|
||||
|
||||
@main.route("/services/<service_id>/sms/send", methods=['GET'])
|
||||
def choose_sms_template(service_id):
|
||||
try:
|
||||
jobs = job_api_client.get_job(service_id)['data']
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
abort(404)
|
||||
else:
|
||||
raise e
|
||||
print("="*80)
|
||||
print(jobs)
|
||||
print(len(jobs))
|
||||
print(bool(len(jobs)))
|
||||
return render_template(
|
||||
'views/choose-sms-template.html',
|
||||
templates=[
|
||||
Template(template) for template in templates_dao.get_service_templates(service_id)['data']
|
||||
],
|
||||
has_jobs=len(jobs),
|
||||
service_id=service_id
|
||||
)
|
||||
|
||||
@@ -127,6 +139,7 @@ def check_sms(service_id, upload_id):
|
||||
template_id = upload_data.get('template_id')
|
||||
raw_template = templates_dao.get_service_template_or_404(service_id, template_id)['data']
|
||||
upload_result = _get_rows(contents, raw_template)
|
||||
session['upload_data']['notification_count'] = len(upload_result['rows'])
|
||||
template = Template(
|
||||
raw_template,
|
||||
values=upload_result['rows'][0] if upload_result['valid'] else {},
|
||||
@@ -147,9 +160,10 @@ def check_sms(service_id, upload_id):
|
||||
upload_data = session['upload_data']
|
||||
original_file_name = upload_data.get('original_file_name')
|
||||
template_id = upload_data.get('template_id')
|
||||
notification_count = upload_data.get('notification_count')
|
||||
session.pop('upload_data')
|
||||
try:
|
||||
job_api_client.create_job(upload_id, service_id, template_id, original_file_name)
|
||||
job_api_client.create_job(upload_id, service_id, template_id, original_file_name, notification_count)
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
abort(404)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from flask import render_template, current_app, abort
|
||||
from flask_wtf import Form
|
||||
from wtforms import StringField, PasswordField, TextAreaField, FileField, validators
|
||||
from utils.template import Template
|
||||
from app.main import main
|
||||
|
||||
|
||||
@@ -17,13 +18,16 @@ def styleguide():
|
||||
message = TextAreaField(u'Message')
|
||||
file_upload = FileField('Upload a CSV file to add your recipients’ details')
|
||||
|
||||
sms = "Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax"
|
||||
|
||||
form = FormExamples()
|
||||
|
||||
form.message.data = "Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax" # noqa
|
||||
|
||||
form.message.data = sms
|
||||
form.validate()
|
||||
|
||||
template = Template({'content': sms})
|
||||
|
||||
return render_template(
|
||||
'views/styleguide.html',
|
||||
form=form
|
||||
form=form,
|
||||
template=template
|
||||
)
|
||||
|
||||
@@ -15,22 +15,10 @@ from app.main.dao import services_dao as sdao
|
||||
@main.route("/services/<service_id>/templates")
|
||||
@login_required
|
||||
def manage_service_templates(service_id):
|
||||
try:
|
||||
jobs = job_api_client.get_job(service_id)['data']
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
abort(404)
|
||||
else:
|
||||
raise e
|
||||
return render_template(
|
||||
'views/manage-templates.html',
|
||||
service_id=service_id,
|
||||
has_jobs=bool(jobs),
|
||||
templates=[
|
||||
Template(template)
|
||||
for template in tdao.get_service_templates(service_id)['data']
|
||||
]
|
||||
)
|
||||
return redirect(url_for(
|
||||
'.choose_sms_template',
|
||||
service_id=service_id
|
||||
))
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/templates/add", methods=['GET', 'POST'])
|
||||
@@ -50,10 +38,10 @@ def add_service_template(service_id):
|
||||
tdao.insert_service_template(
|
||||
form.name.data, form.template_content.data, service_id)
|
||||
return redirect(url_for(
|
||||
'.manage_service_templates', service_id=service_id))
|
||||
'.choose_sms_template', service_id=service_id))
|
||||
return render_template(
|
||||
'views/edit-template.html',
|
||||
h1='Add template',
|
||||
h1='Add a text message template',
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
|
||||
@@ -69,7 +57,7 @@ def edit_service_template(service_id, template_id):
|
||||
tdao.update_service_template(
|
||||
template_id, form.name.data,
|
||||
form.template_content.data, service_id)
|
||||
return redirect(url_for('.manage_service_templates', service_id=service_id))
|
||||
return redirect(url_for('.choose_sms_template', service_id=service_id))
|
||||
|
||||
return render_template(
|
||||
'views/edit-template.html',
|
||||
|
||||
@@ -19,13 +19,14 @@ class JobApiClient(BaseAPIClient):
|
||||
else:
|
||||
return self.get(url='/service/{}/job'.format(service_id))
|
||||
|
||||
def create_job(self, job_id, service_id, template_id, original_file_name):
|
||||
def create_job(self, job_id, service_id, template_id, original_file_name, notification_count):
|
||||
data = {
|
||||
"id": job_id,
|
||||
"template": template_id,
|
||||
"original_file_name": original_file_name,
|
||||
"bucket_name": "service-{}-notify".format(service_id),
|
||||
"file_name": "{}.csv".format(job_id)
|
||||
"file_name": "{}.csv".format(job_id),
|
||||
"notification_count": notification_count
|
||||
}
|
||||
|
||||
resp = self.post(url='/service/{}/job'.format(service_id), data=data)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
from notifications_python_client.notifications import BaseAPIClient
|
||||
from notifications_python_client.errors import (
|
||||
HTTPError,
|
||||
InvalidResponse
|
||||
)
|
||||
from notifications_python_client.errors import HTTPError
|
||||
|
||||
from flask.ext.login import UserMixin
|
||||
|
||||
@@ -34,6 +31,11 @@ class UserApiClient(BaseAPIClient):
|
||||
user_data = self.get(url)
|
||||
return User(user_data['data'], max_failed_login_count=self.max_failed_login_count)
|
||||
|
||||
def get_user_by_email(self, email_address):
|
||||
params = {'email': email_address}
|
||||
user_data = self.get('/user/email', params=params)
|
||||
return User(user_data['data'], max_failed_login_count=self.max_failed_login_count)
|
||||
|
||||
def get_users(self):
|
||||
users_data = self.get("/user")['data']
|
||||
users = []
|
||||
@@ -57,13 +59,6 @@ class UserApiClient(BaseAPIClient):
|
||||
if e.status_code == 400 or e.status_code == 404:
|
||||
return False
|
||||
|
||||
def get_user_by_email(self, email_address):
|
||||
users = self.get_users()
|
||||
user = [u for u in users if u.email_address == email_address]
|
||||
if len(user) == 1:
|
||||
return user[0]
|
||||
return None
|
||||
|
||||
def send_verify_code(self, user_id, code_type, to):
|
||||
data = {'to': to}
|
||||
endpoint = '/user/{0}/{1}-code'.format(user_id, code_type)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% macro file_upload(field, button_text="Choose file") %}
|
||||
<div class="form-group{% if field.errors %} error{% endif %}" data-module="file-upload">
|
||||
<form method="post" enctype="multipart/form-data" class="form-group{% if field.errors %} error{% endif %}" data-module="file-upload">
|
||||
<label class="file-upload-label" for="{{ field.name }}">
|
||||
{{ field.label }}
|
||||
<span class="visually-hidden">{{ field.label }}</span>
|
||||
{% if hint %}
|
||||
<span class="form-hint">
|
||||
{{ hint }}
|
||||
@@ -20,5 +20,7 @@
|
||||
{{ button_text }}
|
||||
</label>
|
||||
<label class="file-upload-filename" for="{{ field.name }}"></label>
|
||||
</div>
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="submit" class="file-upload-submit" value="Submit" />
|
||||
</form>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="submit" class="button{% if destructive %}-destructive{% endif %}" value="{{ button_text }}" />
|
||||
{% endif %}
|
||||
{% if delete_link %}
|
||||
<span class="page-footer-delete-link">
|
||||
or <a href="{{ delete_link }}">{{ delete_link_text }}</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if back_link %}
|
||||
<a class="page-footer-back-link" href="{{ back_link }}">{{ back_link_text }}</a>
|
||||
{% endif %}
|
||||
{% if delete_link %}
|
||||
<span class="page-footer-delete-link">
|
||||
<a href="{{ delete_link }}">{{ delete_link_text }}</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if secondary_link and secondary_link_text %}
|
||||
<a class="page-footer-secondary-link" href="{{ secondary_link }}">{{ secondary_link_text }}</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -55,6 +55,18 @@
|
||||
</td>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro text_field(text) -%}
|
||||
{% call field() %}
|
||||
{{ text }}
|
||||
{% endcall %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro boolean_field(yes) -%}
|
||||
{% call field(status='yes' if yes else 'no') %}
|
||||
{{ "Yes" if yes else "No" }}
|
||||
{% endcall %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro right_aligned_field_heading(text) %}
|
||||
<span class="table-field-heading-right-aligned">{{ text }}</span>
|
||||
{%- endmacro %}
|
||||
|
||||
17
app/templates/components/yes-no.html
Normal file
17
app/templates/components/yes-no.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{% macro yes_no(name, label, current_value=None) %}
|
||||
<fieldset class='yes-no'>
|
||||
<legend class='yes-no-label'>
|
||||
{{ label }}
|
||||
</legend>
|
||||
<div class='yes-no-fields inline'>
|
||||
<label class='block-label'>
|
||||
<input type='radio' name='{{ name }}' {% if current_value == True %}checked{% endif %} />
|
||||
Yes
|
||||
</label>
|
||||
<label class='block-label'>
|
||||
<input type='radio' name='{{ name }}' {% if current_value == False %}checked{% endif %} />
|
||||
No
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
{% endmacro %}
|
||||
@@ -5,7 +5,7 @@
|
||||
{{ banner(
|
||||
message,
|
||||
'default' if ((category == 'default') or (category == 'default_with_tick')) else 'dangerous',
|
||||
delete_button="Yes, delete this template" if 'delete' == category else None,
|
||||
delete_button="Yes, delete" if 'delete' == category else None,
|
||||
with_tick=True if category == 'default_with_tick' else False
|
||||
)}}
|
||||
{% endfor %}
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
<li><a href="{{ url_for('.send_email', service_id=service_id) }}">Send emails</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.manage_service_templates', service_id=service_id) }}">Manage templates</a></li>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=service_id) }}">Manage users</a></li>
|
||||
<li><a href="{{ url_for('.service_settings', service_id=service_id) }}">Manage service settings</a></li>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=service_id) }}">Manage team</a></li>
|
||||
<li><a href="{{ url_for('.service_settings', service_id=service_id) }}">Manage settings</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.documentation', service_id=service_id) }}">Developer documentation</a></li>
|
||||
<li><a href="{{ url_for('.api_keys', service_id=service_id) }}">API keys</a></li>
|
||||
<li><a href="{{ url_for('.documentation', service_id=service_id) }}">Developer documentation</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
|
||||
<p>
|
||||
<p class='table-show-more-link'>
|
||||
<a href="{{ url_for('.create_api_key', service_id=service_id) }}">Create a new API key</a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -45,12 +45,7 @@
|
||||
<a href="{{url_for('.send_sms', service_id=service_id, template_id=template.id)}}" class="page-footer-back-link">Back</a>
|
||||
</form>
|
||||
{% else %}
|
||||
<form method="post" action="{{ url_for('.send_sms', service_id=service_id, template_id=template.id) }}" enctype="multipart/form-data">
|
||||
{{file_upload(form.file, button_text='Choose a CSV file')}}
|
||||
{{ page_footer(
|
||||
"Upload"
|
||||
) }}
|
||||
</form>
|
||||
{{file_upload(form.file, button_text='Upload a CSV file')}}
|
||||
{% endif %}
|
||||
|
||||
{% call(item) list_table(
|
||||
|
||||
@@ -14,6 +14,15 @@
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
|
||||
{% if templates %}
|
||||
{% if not has_jobs %}
|
||||
{{ banner(
|
||||
"""
|
||||
Send yourself a test message
|
||||
""",
|
||||
subhead='Next step',
|
||||
type="tip"
|
||||
)}}
|
||||
{% endif %}
|
||||
<div class="grid-row">
|
||||
{% for template in templates %}
|
||||
<div class="column-two-thirds">
|
||||
@@ -23,18 +32,16 @@
|
||||
<div class="sms-message-use-links">
|
||||
<a href="{{ url_for(".send_sms", service_id=service_id, template_id=template.id) }}">Add recipients</a>
|
||||
<a href="{{ url_for(".send_sms_to_self", service_id=service_id, template_id=template.id) }}">Send yourself a test</a>
|
||||
<a href="{{ url_for(".edit_service_template", service_id=service_id, template_id=template.id) }}">Edit template</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ banner(
|
||||
'<a href="{}">Add a text message template</a> to start sending messages'.format(
|
||||
url_for(".add_service_template", service_id=service_id)
|
||||
)|safe,
|
||||
type="tip"
|
||||
)}}
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
<a href="{{ url_for('.add_service_template', service_id=service_id) }}" class="button">Add a new template</a>
|
||||
</p>
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
delete_link=url_for('.delete_service_template', service_id=service_id, template_id=template_id) if template_id or None,
|
||||
delete_link_text='delete this template',
|
||||
secondary_link=url_for('.manage_service_templates', service_id=service_id),
|
||||
secondary_link_text='Back to templates'
|
||||
delete_link_text='Delete this template',
|
||||
back_link=url_for('.choose_sms_template', service_id=service_id),
|
||||
back_link_text='Cancel'
|
||||
) }}
|
||||
</form>
|
||||
|
||||
|
||||
50
app/templates/views/invite-user.html
Normal file
50
app/templates/views/invite-user.html
Normal file
@@ -0,0 +1,50 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/yes-no.html" import yes_no %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
|
||||
{% block page_title %}
|
||||
Manage users – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">
|
||||
{{ user.name or user.email_localpart or "Add a new team member" }}
|
||||
</h1>
|
||||
|
||||
<div class="grid-row">
|
||||
<form method="post" class="column-three-quarters">
|
||||
|
||||
{% if user %}
|
||||
<p class='bottom-gutter'>
|
||||
{{ current_user.email_address }}
|
||||
</p>
|
||||
{% else %}
|
||||
{{ textbox(form.email_address, hint='Email address must end in .gov.uk', width='1-1') }}
|
||||
{% endif %}
|
||||
|
||||
<fieldset class='yes-no-wrapper'>
|
||||
<legend class='heading-small'>
|
||||
Permissions
|
||||
</legend>
|
||||
{{ yes_no('send_messages', 'Send messages', user.permission_send_messages) }}
|
||||
{{ yes_no('manage_service', 'Manage service', user.permission_manage_service) }}
|
||||
{{ yes_no('manage_api_keys', 'Manage API keys', user.permission_manage_api_keys) }}
|
||||
</fieldset>
|
||||
|
||||
{% if user %}
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
delete_link=url_for('.delete_user', service_id=service_id, user_id=user_id),
|
||||
delete_link_text='Delete this account',
|
||||
back_link=url_for('.manage_users', service_id=service_id),
|
||||
back_link_text='Cancel'
|
||||
) }}
|
||||
{% else %}
|
||||
{{ page_footer('Send invitation email') }}
|
||||
{% endif %}
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,53 +0,0 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/sms-message.html" import sms_message %}
|
||||
{% from "components/email-message.html" import email_message %}
|
||||
{% from "components/browse-list.html" import browse_list %}
|
||||
|
||||
{% block page_title %}
|
||||
Manage templates – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">Manage templates</h1>
|
||||
|
||||
|
||||
{% if not has_jobs %}
|
||||
{{ banner(
|
||||
'<a href="{}">Send yourself a text message</a>'.format(
|
||||
url_for(".choose_sms_template", service_id=service_id)
|
||||
)|safe,
|
||||
subhead='Next step',
|
||||
type="tip"
|
||||
)}}
|
||||
{% endif %}
|
||||
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
|
||||
{% for template in templates %}
|
||||
{% if template.template_type == 'email' %}
|
||||
{{ email_message(
|
||||
template.get_field('subject'),
|
||||
template.get_field('content'),
|
||||
name=template.get_field('name'),
|
||||
edit_link=url_for('.edit_service_template', service_id=service_id, template_id=template.id)
|
||||
) }}
|
||||
{% else %}
|
||||
{{ sms_message(
|
||||
template.formatted_as_markup,
|
||||
name=template.name,
|
||||
id=template.id,
|
||||
edit_link=url_for('.edit_service_template', service_id=service_id, template_id=template.id)
|
||||
) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<p>
|
||||
<a href="{{ url_for('.add_service_template', service_id=service_id) }}" class="button">Add new template</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,65 +1,55 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/table.html" import list_table, row, field %}
|
||||
{% from "components/table.html" import list_table, row, field, boolean_field, hidden_field_heading %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
|
||||
{% set table_options = {
|
||||
'field_headings': [
|
||||
'Name', 'Send messages', 'Manage service', 'Manage API keys', hidden_field_heading('Link to change')
|
||||
],
|
||||
'field_headings_visible': True,
|
||||
'caption_visible': True
|
||||
} %}
|
||||
|
||||
{% block page_title %}
|
||||
Manage users – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">Manage users</h1>
|
||||
<h1 class="heading-large">
|
||||
Manage team
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<a href="#" class="button">Invite users</a>
|
||||
</p>
|
||||
<a href="{{ url_for('.invite_user', service_id=service_id) }}" class="button">Invite a team member</a>
|
||||
|
||||
{% call(item) list_table(
|
||||
users,
|
||||
caption='Active users',
|
||||
field_headings=['Name', 'Send messages', 'Manage Service', 'Manage API keys', 'Link to change'],
|
||||
field_headings_visible=True,
|
||||
caption_visible=True
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.name }}
|
||||
{% call(item) list_table(
|
||||
users, caption='Active', **table_options
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ current_user.name }}
|
||||
{% endcall %}
|
||||
{{ boolean_field(item.permission_send_messages) }}
|
||||
{{ boolean_field(item.permission_manage_service) }}
|
||||
{{ boolean_field(item.permission_manage_api_keys) }}
|
||||
{% call field(align='right') %}
|
||||
<a href="{{ url_for('.edit_user', service_id=service_id, user_id=0)}}">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_send_messages else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_manage_service else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_manage_api_keys else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
<a href="#">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
{% call(item) list_table(
|
||||
invited_users,
|
||||
caption='Invited users',
|
||||
field_headings=['Name', 'Send messages', 'Manage Service', 'Manage API keys', 'Link to change'],
|
||||
field_headings_visible=True,
|
||||
caption_visible=True
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.email_localpart }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_send_messages else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_manage_service else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ "✔" if item.permission_manage_api_keys else "❌" }}
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
<a href="#">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% if invited_users %}
|
||||
{% call(item) list_table(
|
||||
invited_users, caption='Invited', **table_options
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.email_localpart }}
|
||||
{% endcall %}
|
||||
{{ boolean_field(item.permission_send_messages) }}
|
||||
{{ boolean_field(item.permission_manage_service) }}
|
||||
{{ boolean_field(item.permission_manage_api_keys) }}
|
||||
{% call field(align='right') %}
|
||||
<a href="{{ url_for('.edit_user', service_id=service_id, user_id=item.id)}}">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -12,24 +12,23 @@
|
||||
|
||||
<h1 class="heading-large">Add recipients</h1>
|
||||
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
|
||||
{{ sms_message(template.formatted_as_markup) }}
|
||||
|
||||
{{ banner(
|
||||
'You can upload real data, but we’ll only send to your mobile number until you <a href="{}">request to go live</a>'|safe,
|
||||
'info'
|
||||
)}}
|
||||
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
{{ sms_message(template.formatted_as_markup) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{file_upload(form.file, button_text='Choose a CSV file')}}
|
||||
{{file_upload(form.file, button_text='Upload a CSV file')}}
|
||||
|
||||
<p>
|
||||
<a href="{{ url_for('.get_example_csv', service_id=service_id, template_id=template.id) }}">Download an example CSV file</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ url_for('.get_example_csv', service_id=service_id, template_id=template.id) }}">Download an example CSV file</a>
|
||||
</p>
|
||||
|
||||
{{ page_footer(
|
||||
"Continue to preview"
|
||||
) }}
|
||||
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% if not jobs %}
|
||||
{% if not template_count and not jobs %}
|
||||
{{ banner(
|
||||
"""
|
||||
<ol>
|
||||
@@ -41,6 +41,16 @@
|
||||
subhead='Get started',
|
||||
type="tip"
|
||||
)}}
|
||||
{% elif not jobs %}
|
||||
{{ banner(
|
||||
"""
|
||||
<a href='{}'>Send yourself a text message</a>
|
||||
""".format(
|
||||
url_for(".choose_sms_template", service_id=service_id)
|
||||
)|safe,
|
||||
subhead='Next step',
|
||||
type="tip"
|
||||
)}}
|
||||
{% else %}
|
||||
{% call(item) list_table(
|
||||
jobs,
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
{% from "components/browse-list.html" import browse_list %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
{% from "components/sms-message.html" import sms_message %}
|
||||
{% from "components/table.html" import mapping_table, list_table, row, field, right_aligned_field_heading %}
|
||||
{% from "components/email-message.html" import email_message %}
|
||||
{% from "components/table.html" import mapping_table, list_table, row, field, text_field, boolean_field, right_aligned_field_heading %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/file-upload.html" import file_upload %}
|
||||
{% from "components/yes-no.html" import yes_no %}
|
||||
{% from "components/api-key.html" import api_key %}
|
||||
|
||||
{% block page_title %}
|
||||
@@ -25,21 +27,26 @@
|
||||
</p>
|
||||
|
||||
<h2 class="heading-large">Banner</h2>
|
||||
<p>Used to show the status of a thing or action.</p>
|
||||
<div class="grid-row">
|
||||
<div class="column-three-quarters">
|
||||
<p>Used to show the status of a thing or action.</p>
|
||||
|
||||
{{ banner("You sent 1,234 text messages", with_tick=True) }}
|
||||
{{ banner("You sent 1,234 text messages", with_tick=True) }}
|
||||
|
||||
{{ banner('You’re not allowed to do this', 'dangerous')}}
|
||||
{{ banner('You’re not allowed to do this', 'dangerous')}}
|
||||
|
||||
{{ banner('Are you sure you want to delete?', 'dangerous', delete_button="Yes, delete this thing")}}
|
||||
{{ banner('Are you sure you want to delete?', 'dangerous', delete_button="Yes, delete this thing")}}
|
||||
|
||||
{{ banner(
|
||||
'<a href="#">Send your first message</a>'|safe,
|
||||
subhead='Get started',
|
||||
type='tip'
|
||||
)}}
|
||||
{{ banner(
|
||||
'<a href="#">Send your first message</a>'|safe,
|
||||
subhead='Get started',
|
||||
type='tip'
|
||||
)}}
|
||||
|
||||
{{ banner('You could go to jail', 'important')}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ banner('You could go to jail', 'important')}}
|
||||
|
||||
<h2 class="heading-large">Big number</h2>
|
||||
|
||||
@@ -118,7 +125,7 @@
|
||||
|
||||
<h2 class="heading-large">SMS message</h2>
|
||||
|
||||
<p>Used to show, preview or choose an SMS message.</p>
|
||||
<p>Used to show, preview or choose an SMS template.</p>
|
||||
|
||||
<div class="grid-row">
|
||||
<div class="column-half">
|
||||
@@ -127,82 +134,105 @@
|
||||
name='Two week reminder',
|
||||
) }}
|
||||
{{ sms_message(
|
||||
'Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax'
|
||||
template.formatted_as_markup
|
||||
) }}
|
||||
{{ sms_message(
|
||||
'Your vehicle tax for registration number is due on date. Renew online at www.gov.uk/vehicle-tax',
|
||||
'Your vehicle tax for LC12 BFL is due on 1 March 2016. Renew online at www.gov.uk/vehicle-tax',
|
||||
'+44 7700 900 306'
|
||||
) }}
|
||||
{{ sms_message(
|
||||
'Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax',
|
||||
template.formatted_as_markup,
|
||||
name='Two week reminder',
|
||||
edit_link='#'
|
||||
) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="heading-large">Email message</h2>
|
||||
|
||||
<p>Used to show, preview or choose an email template.</p>
|
||||
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
{{ email_message(
|
||||
subject="Vehicle tax reminder",
|
||||
body="Dear Alice Smith,\n\nYour vehicle tax for LC12 BFL is due on 1 March 2016.\n\nRenew online at www.gov.uk/vehicle-tax",
|
||||
from_name="Vehicle tax",
|
||||
from_address="vehicle.tax@notifications.service.gov.uk",
|
||||
name="Two week reminder",
|
||||
) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="heading-large">Tables</h2>
|
||||
{% call mapping_table(
|
||||
caption='Account settings',
|
||||
field_headings=['Label', 'Value', 'Action'],
|
||||
field_headings_visible=False,
|
||||
caption_visible=True
|
||||
) %}
|
||||
{% call row() %}
|
||||
{% call field() %}
|
||||
Username
|
||||
<div class="grid-row">
|
||||
<div class="column-three-quarters">
|
||||
<p>
|
||||
Used for comparing rows of data.
|
||||
</p>
|
||||
{% call mapping_table(
|
||||
caption='Account settings',
|
||||
field_headings=['Label', 'True', 'False', 'Action'],
|
||||
field_headings_visible=False,
|
||||
caption_visible=True
|
||||
) %}
|
||||
{% call row() %}
|
||||
{{ text_field('Username' )}}
|
||||
{{ boolean_field(True) }}
|
||||
{{ boolean_field(False) }}
|
||||
{% call field(align='right') %}
|
||||
<a href="#">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
admin
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
<a href="#">Change</a>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
{% call(item) list_table(
|
||||
[
|
||||
{
|
||||
'file': 'dispatch_20151114.csv', 'status': 'Queued'
|
||||
},
|
||||
{
|
||||
'file': 'dispatch_20151117.csv', 'status': 'Delivered'
|
||||
},
|
||||
{
|
||||
'file': 'remdinder_monday.csv', 'status': 'Failed'
|
||||
}
|
||||
],
|
||||
caption='Messages',
|
||||
field_headings=['File', right_aligned_field_heading('Status')],
|
||||
field_headings_visible=True,
|
||||
caption_visible=False
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.file }}
|
||||
{% endcall %}
|
||||
{% call field(
|
||||
align='right',
|
||||
status='error' if item.status == 'Failed' else 'default'
|
||||
) %}
|
||||
{{ item.status }}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% call(item) list_table(
|
||||
[
|
||||
{
|
||||
'file': 'dispatch_20151114.csv', 'status': 'Queued'
|
||||
},
|
||||
{
|
||||
'file': 'dispatch_20151117.csv', 'status': 'Delivered'
|
||||
},
|
||||
{
|
||||
'file': 'remdinder_monday.csv', 'status': 'Failed'
|
||||
}
|
||||
],
|
||||
caption='Messages',
|
||||
field_headings=['File', right_aligned_field_heading('Status')],
|
||||
field_headings_visible=True,
|
||||
caption_visible=False
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.file }}
|
||||
{% endcall %}
|
||||
{% call field(
|
||||
align='right',
|
||||
status='error' if item.status == 'Failed' else 'default'
|
||||
) %}
|
||||
{{ item.status }}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
{% call(item) list_table(
|
||||
[],
|
||||
caption='Jobs',
|
||||
field_headings=['Job', 'Time'],
|
||||
caption_visible=True,
|
||||
empty_message='You haven’t scheduled any jobs yet'
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.job }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ item.time }}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
{% call(item) list_table(
|
||||
[],
|
||||
caption='Jobs',
|
||||
field_headings=['Job', 'Time'],
|
||||
caption_visible=True,
|
||||
empty_message='You haven’t scheduled any jobs yet'
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.job }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ item.time }}
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
<p class="table-show-more-link">
|
||||
<a href="#">Add a job now</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="heading-large">Textbox</h2>
|
||||
{{ textbox(form.username) }}
|
||||
@@ -213,6 +243,17 @@
|
||||
<h2 class="heading-large">File upload</h2>
|
||||
{{ file_upload(form.file_upload) }}
|
||||
|
||||
<h2 class="heading-large">Yes/no</h2>
|
||||
<div class="grid-row">
|
||||
<div class='column-half'>
|
||||
<fieldset class='yes-no-wrapper'>
|
||||
{{ yes_no('manage_service', 'Manage service', True) }}
|
||||
{{ yes_no('templates', 'Create templates', True) }}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="heading-large">API key</h2>
|
||||
|
||||
{{ api_key('d30512af92e1386d63b90e5973b49a10') }}
|
||||
|
||||
Reference in New Issue
Block a user