aboutsummaryrefslogtreecommitdiffstats
path: root/templates/web/base/admin
diff options
context:
space:
mode:
Diffstat (limited to 'templates/web/base/admin')
-rw-r--r--templates/web/base/admin/bodies/_category_field.html17
-rw-r--r--templates/web/base/admin/bodies/body.html33
-rw-r--r--templates/web/base/admin/bodies/contact-form.html193
-rw-r--r--templates/web/base/admin/bodies/open311-form-fields.html4
-rw-r--r--templates/web/base/admin/category-checkboxes.html33
-rw-r--r--templates/web/base/admin/config_page.html9
-rw-r--r--templates/web/base/admin/council_contacts.txt2
-rw-r--r--templates/web/base/admin/defecttypes/list.html3
-rw-r--r--templates/web/base/admin/exordefects/index.html39
-rw-r--r--templates/web/base/admin/extra-metadata-form.html98
-rw-r--r--templates/web/base/admin/extra-metadata-item.html110
-rw-r--r--templates/web/base/admin/extra-metadata-option.html29
-rw-r--r--templates/web/base/admin/index.html47
-rw-r--r--templates/web/base/admin/list_updates.html2
-rw-r--r--templates/web/base/admin/manifesttheme/form.html71
-rw-r--r--templates/web/base/admin/manifesttheme/index.html35
-rw-r--r--templates/web/base/admin/problem_row.html4
-rw-r--r--templates/web/base/admin/report-category.html17
-rw-r--r--templates/web/base/admin/report_blocks.html4
-rw-r--r--templates/web/base/admin/reports/edit.html (renamed from templates/web/base/admin/report_edit.html)15
-rw-r--r--templates/web/base/admin/reports/index.html (renamed from templates/web/base/admin/reports.html)2
-rw-r--r--templates/web/base/admin/responsepriorities/edit.html57
-rw-r--r--templates/web/base/admin/responsepriorities/index.html58
-rw-r--r--templates/web/base/admin/responsepriorities/list.html36
-rw-r--r--templates/web/base/admin/roles/form.html32
-rw-r--r--templates/web/base/admin/roles/index.html35
-rw-r--r--templates/web/base/admin/states/index.html2
-rw-r--r--templates/web/base/admin/stats/index.html17
-rw-r--r--templates/web/base/admin/templates/edit.html (renamed from templates/web/base/admin/template_edit.html)6
-rw-r--r--templates/web/base/admin/templates/index.html (renamed from templates/web/base/admin/templates_index.html)2
-rw-r--r--templates/web/base/admin/templates/view.html (renamed from templates/web/base/admin/templates.html)4
-rw-r--r--templates/web/base/admin/triage/_inspect.html77
-rw-r--r--templates/web/base/admin/triage/_list-filters.html53
-rw-r--r--templates/web/base/admin/triage/index.html42
-rw-r--r--templates/web/base/admin/update_edit.html2
-rw-r--r--templates/web/base/admin/users/edit.html2
-rw-r--r--templates/web/base/admin/users/form.html42
-rw-r--r--templates/web/base/admin/users/import.html11
-rw-r--r--templates/web/base/admin/users/index.html59
-rw-r--r--templates/web/base/admin/users/log.html72
40 files changed, 951 insertions, 425 deletions
diff --git a/templates/web/base/admin/bodies/_category_field.html b/templates/web/base/admin/bodies/_category_field.html
new file mode 100644
index 000000000..8c5a1c352
--- /dev/null
+++ b/templates/web/base/admin/bodies/_category_field.html
@@ -0,0 +1,17 @@
+<div class="admin-hint">
+ <p>
+ [% loc('Choose a <strong>category</strong> name that makes sense to the public (e.g., "Pothole", "Street lighting") but is helpful
+ to the body too. These will appear in the drop-down menu on the report-a-problem page.') %]
+ <br>
+ [% loc("If two or more bodies serve the same location, FixMyStreet combines identical categories into a single entry in
+ the menu. Make sure you use the same category name in the bodies if you want this to happen.") %]
+ </p>
+</div>
+
+<p>
+ <strong>[% loc('Category') %] </strong><input type="text" class="form-control" name="category" size="30" value="[% contact.category | html %]" required>
+</p>
+
+[% IF contact.in_storage %]
+ <input type="hidden" name="current_category" value="[% current_contact.category | html %]" >
+[% END %]
diff --git a/templates/web/base/admin/bodies/body.html b/templates/web/base/admin/bodies/body.html
index 8f298676e..0db50e97b 100644
--- a/templates/web/base/admin/bodies/body.html
+++ b/templates/web/base/admin/bodies/body.html
@@ -70,15 +70,16 @@
<table cellspacing="0" cellpadding="2" border="1" id="admin_contacts">
<tr>
- <th>[% loc('Category') %]</th>
- <th>[% loc('State') %]</th>
- <th>[% loc('Last editor') %]</th>
- <th>[% loc('Note') %]</th>
+ <th scope="col">[% loc('Category') %]</th>
+ <th scope="col">[% loc('State') %]</th>
+ <th scope="col">[% loc('Last editor') %]</th>
+ <th scope="col">[% loc('Note') %]</th>
[% IF any_not_confirmed %]
- <th>[% loc('Confirm') %]</th>
+ <th scope="col">[% loc('Confirm') %]</th>
[% END %]
</tr>
- [% WHILE ( cat = contacts.next ) %]
+
+ [% BLOCK category_row %]
<tr [% IF cat.state == 'deleted' %]class="is-deleted"[% END %]>
<td class="contact-category"><a href="[% c.uri_for_action( '/admin/bodies/edit', [ body_id ], cat.category ) %]">[% cat.category_display | html %]</a>
<br>[% cat.email | html %]</td>
@@ -102,6 +103,24 @@
[% END %]
</tr>
[% END %]
+
+ [%~ IF category_groups.size ~%]
+ [%~ FOREACH group IN category_groups ~%]
+ [% IF group.name %]
+ <tr>
+ <th class="group" colspan="[% any_not_confirmed ? 5 : 4 %]" scope="colgroup">[% group.name %]</th>
+ </tr>
+ [% END %]
+ [%~ FOREACH cat IN group.categories ~%]
+ [% INCLUDE category_row %]
+ [%~ END ~%]
+ [%~ END =%]
+ [%~ ELSE ~%]
+ [%~ FOREACH cat IN contacts ~%]
+ [% INCLUDE category_row %]
+ [%~ END =%]
+ [%~ END ~%]
+
</table>
[% IF any_not_confirmed %]
@@ -129,7 +148,7 @@
[% IF errors %]
<div class="fms-admin-warning">
- [% errors.values.join('<br>') %]
+ [% FOR error IN errors.values %][% error %][% IF NOT loop.last %]<br>[% END %][% END %]
</div>
[% INCLUDE 'admin/bodies/contact-form.html' translations=contact_translations %]
[% ELSE %]
diff --git a/templates/web/base/admin/bodies/contact-form.html b/templates/web/base/admin/bodies/contact-form.html
index c55c5c036..35fab4541 100644
--- a/templates/web/base/admin/bodies/contact-form.html
+++ b/templates/web/base/admin/bodies/contact-form.html
@@ -1,102 +1,74 @@
<form method="post" action="[% c.uri_for_action('admin/bodies/edit', [ body_id ] ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8" id="category_edit">
- [% IF contact.in_storage %]
- <p>
- <h1>[% contact.category_display | html %]</h1>
- <input type="hidden" name="category" value="[% contact.category | html %]" >
- </p>
- [% ELSE %]
- <div class="admin-hint">
- <p>
- [% loc('Choose a <strong>category</strong> name that makes sense to the public (e.g., "Pothole", "Street lighting") but is helpful
- to the body too. These will appear in the drop-down menu on the report-a-problem page.') %]
- <br>
- [% loc("If two or more bodies serve the same location, FixMyStreet combines identical categories into a single entry in
- the menu. Make sure you use the same category name in the bodies if you want this to happen.") %]
- </p>
- </div>
- <p>
- <strong>[% loc('Category') %] </strong><input type="text" class="form-control" name="category" size="30" value="[% contact.category | html %]" required>
- </p>
- [% END %]
+ [% PROCESS 'admin/bodies/_category_field.html' %]
[% INCLUDE 'admin/bodies/_translations.html' %]
- <div class="admin-hint">
- <p>
- [% loc("The <strong>email address</strong> is the destination to which reports about this category will be sent.
- Other categories for this body may have the same email address.") %]
+ <label for="destination">[% loc('Destination') %]</label>
+ <p class="form-hint" id="destination-hint">
+ [% IF body.can_be_devolved %]
+ [% loc('An email address or service ID (Open311 or similar).') %]
+ [% ELSIF body.send_method == 'Open311' %]
+ [% loc('A service ID (Open311 or similar).') %]
+ [% ELSIF body.send_method.match('Email') OR NOT body.send_method %]
+ [% loc('An email address.') %]
+ [% ELSE %]
+ [% loc('An email address or service ID (Open311 or similar).') %]
+ [% END %]
</p>
- [% IF (body.send_method AND body.send_method.match('Email')) OR body.can_be_devolved %]
- <p>
- [% loc("If you're using <strong>a send method that is not email</strong>, enter the service ID (Open311) or equivalent identifier here.") %]
- </p>
- [% END %]
- </div>
+ <input type="text" class="form-control" id="destination" aria-describedby="destination-hint" name="email" size="30" value="[% contact.email | html %]" required>
- <p>
- <strong>[% loc('Email address') %] </strong><input type="text" class="form-control" name="email" size="30" value="[% contact.email | html %]" required>
- </p>
+ <fieldset>
+ <legend>[% loc('State') %]</legend>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="state" id="state-unconfirmed" aria-describedby="state-unconfirmed-hint" value="unconfirmed"[% ' checked' IF contact.state == 'unconfirmed' %]>
+ <label for="state-unconfirmed">[% loc('Unconfirmed') %]</label>
+ <p class="form-hint" id="state-unconfirmed-hint">[% loc('You are not sure of the origin or validity of the contact.') %]</p>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="state" id="state-confirmed" aria-describedby="state-confirmed-hint" value="confirmed"[% ' checked' IF contact.state == 'confirmed' || contact.state == "" %]>
+ <label for="state-confirmed">[% loc('Confirmed') %]</label>
+ <p class="form-hint" id="state-confirmed-hint">[% loc('The contact has been confirmed as correct.') %]</p>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="state" id="state-inactive" aria-describedby="state-inactive-hint" value="inactive"[% ' checked' IF contact.state == 'inactive' %]>
+ <label for="state-inactive">[% loc('Inactive') %]</label>
+ <p class="form-hint" id="state-inactive-hint">[% loc('Prevent new reports from using this category, but keep it available in map filters.') %]</p>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="state" id="state-deleted" aria-describedby="state-deleted-hint" value="deleted"[% ' checked' IF contact.state == 'deleted' %]>
+ <label for="state-deleted">[% loc('Deleted') %]</label>
+ <p class="form-hint" id="state-deleted-hint">[% loc('Prevent new reports from using this category, <em>and</em> also remove it from map filters.') %]</p>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="state" id="state-staff" aria-describedby="state-staff-hint" value="staff"[% ' checked' IF contact.state == 'staff' %]>
+ <label for="state-staff">[% loc('Staff only') %]</label>
+ <p class="form-hint" id="state-staff-hint">[% loc('Only staff users will be able to add reports in this category.') %]</p>
+ </div>
+ </fieldset>
- <div class="admin-hint">
- <p>
- [%
-loc("Use <strong>confirmed</strong> to indicate that this contact has been
-confirmed as correct. If you are not sure of the origin or validity of the
-contact, use <strong>unconfirmed</strong>. <strong>inactive</strong> will
-remove the category from use when reporting problems, but keep it available in
-map filters, and <strong>deleted</strong> will remove the category from there
-as well.") %]
+ <p class="form-check">
+ <input type="checkbox" name="non_public" value="1" id="non_public" [% ' checked' IF contact.non_public %]>
+ <label for="non_public">[% loc('Hide reports made in this category') %]</label>
+ <span class='form-hint'>[% loc('Use this for issues that you want to allow users to report, but for which there is no public interest in displaying the report, like requesting an extra rubbish bin at a specific address.') %]</span>
</p>
- </div>
- <p>
- <label for="state">[% loc('State') %]</label>
- <select name="state" id="state">
- <option value="unconfirmed"[% ' selected' IF contact.state == 'unconfirmed' %]>[% loc('Unconfirmed') %]
- <option value="confirmed"[% ' selected' IF contact.state == 'confirmed' || contact.state == "" %]>[% loc('Confirmed') %]
- <option value="inactive"[% ' selected' IF contact.state == 'inactive' %]>[% loc('Inactive') %]
- <option value="deleted"[% ' selected' IF contact.state == 'deleted' %]>[% loc('Deleted') %]
- </select>
- </p>
- <div class="admin-hint">
- <p>
- [% loc("Check <strong>private</strong> if reports in this category should <strong>never be displayed on the website</strong>.
- <br>
- Normally, categories are not private.
- <br>
- This is suitable for issues that you want to allow users to report to the body, but for which there is no public
- interest in displaying the report. In the UK, we've used this for services like requesting an extra rubbish bin
- at a specific address.") %]
+ <p class="form-check">
+ <input type="checkbox" name="disable" value="1" id="disable" data-toggle-visibility="#js-disable-form-message-box" [% ' checked' IF contact.disable_form_field %]>
+ <label for="disable">[% loc('Disable form when this category is selected') %]</label>
</p>
- </div>
- <p>
- <input type="checkbox" name="non_public" value="1" id="non_public" [% ' checked' IF contact.non_public %]>
- <label for="non_public" class="inline">[% loc('Private') %]</label>
- </p>
- <div class="admin-hint">
- <p>
- [% loc("Check <strong>inspection required</strong> if reports in this category <strong>must be inspected</strong> before being sent.") %]
+ <p class="form-group form-group--indented [% 'hidden-js' IF NOT contact.disable_form_field %]" id="js-disable-form-message-box">
+ <label for="disabled-message">[% loc('Message to show when form is disabled (HTML permitted)') %]</label>
+ <textarea id="disabled-message" name="disable_message" class="form-control">[% contact.disable_form_field.description %]</textarea>
</p>
- </div>
- <p>
- <input type="checkbox" name="inspection_required" value="1" id="inspection_required" [% 'checked' IF contact.get_extra_metadata('inspection_required') %]>
- <label for="inspection_required" class="inline">[% loc('Inspection required') %]</label>
- </p>
- <div class="admin-hint [% 'hidden' UNLESS contact.get_extra_metadata('inspection_required') %]">
- <p>
- [% loc("Reports will automatically be sent without needing to be inspected if the user's <strong>reputation</strong> is at or above this value. Set to <strong>0</strong> if all reports must be inspected regardless.") %]
- </p>
- </div>
- <p [% 'class=hidden' UNLESS contact.get_extra_metadata('inspection_required') %]>
- <label>
- [% loc('Reputation threshold') %]
- <input type="text" class="form-control" name="reputation_threshold" id="reputation_threshold"
- value="[% contact.get_extra_metadata('reputation_threshold') | html %]" size="30">
- </label>
- </p>
+ [% IF body.send_method == 'Open311' %]
+ <p class="form-check">
+ <input type="checkbox" name="open311_protect" value="1" id="open311_protect"[% ' checked' IF contact.get_extra_metadata('open311_protect') %]>
+ <label for="open311_protect">[% loc("Protect this category's name and group(s) from Open311 changes") %]</label>
+ </p>
+ [% END %]
[% IF body.can_be_devolved %]
<div class="admin-hint">
@@ -121,34 +93,37 @@ as well.") %]
[% END %]
[% IF c.cobrand.enable_category_groups %]
- <div class="admin-hint">
- <p>
- [% loc(
- "The <strong>group</strong> is used for the top-level category field when
- subcategory grouping is enabled."
- ) %]
- </p>
- </div>
<p>
<label>
- [% loc('Group') %]
- <input class="form-control" type="text" name="group" value="[% contact.extra.group | html %]" size="30">
+ [% loc('Parent categories') %]
+ [% IF contact.extra.group %]
+ [% FOR group IN contact.extra.group %]
+ <input class="form-control" type="text" name="group" value="[% group | html %]" size="30">
+ [% END %]
+ [% ELSE %]
+ <input class="form-control" type="text" name="group" value="" size="30">
+ [% END %]
+ <input class="hidden-js js-group-item-template form-control" type="text" name="group" value="" size="30">
+ <p class="hidden-nojs">
+ <button type="button" class="btn btn--small js-group-item-add">[% loc('Add another parent category') %]</button>
+ </p>
</label>
</p>
[% END %]
+ <h2>[% loc('Extra data:') %] </h2>
+ <dl>
+ [% FOR pair IN contact.get_extra_metadata %]
+ <dt>[% pair.key %]</dt> <dd>[% pair.value OR '<em>-</em>' %]</dd>
+ [% END %]
+ </dl>
+ [% INCLUDE 'admin/extra-metadata-form.html' metas=(contact.get_metadata_for_editing OR []) %]
- <div class="admin-hint">
- <p>
- [% loc("Use this field to record details that are only displayed in the admin. Input is not shown publicly, and is not sent to the body.") %]
+ <p class="form-group" style="margin-top: 2em">
+ <label for="note">[% loc('Summarise your changes') %]</label>
+ <span class="form-hint" id="note-hint">[% loc("If you’ve made changes, leave a note explaining what, for other admins to see.") %]</span>
+ <input class="form-control" type="text" id="note" name="note" size="30" aria-describedby="note-hint"[% ' required' UNLESS c.config.STAGING_SITE %]>
</p>
- </div>
- <p>
- <label>
- [% loc('Summarise your changes') %]
- <input class="form-control" type="text" name="note" size="30" required>
- </label>
- </p>
<p>
<input type="hidden" name="posted" value="new" >
@@ -156,11 +131,5 @@ as well.") %]
<input type="submit" class="btn" name="Create category" value="[% contact.in_storage ? loc('Save changes') : loc('Create category') %]" >
</p>
- <h2>[% loc('Extra data:') %] </h2>
- <dl>
- [% FOR pair IN contact.get_extra_metadata %]
- <dt>[% pair.key %]</dt> <dd>[% pair.value %]</dd>
- [% END %]
- </dl>
- [% INCLUDE 'admin/extra-metadata-form.html' metas=(contact.get_metadata_for_editing OR []) %]
+
</form>
diff --git a/templates/web/base/admin/bodies/open311-form-fields.html b/templates/web/base/admin/bodies/open311-form-fields.html
index bdd4ad935..dbb0f84e2 100644
--- a/templates/web/base/admin/bodies/open311-form-fields.html
+++ b/templates/web/base/admin/bodies/open311-form-fields.html
@@ -90,7 +90,7 @@
<label for"comment_user_id">[% loc('User ID to attribute fetched comments to') %]</label>
<input type="text" class="form-control" name="comment_user_id" value="[% object.comment_user_id %]">
[% IF object.comment_user_id %]
- <a href="[% c.uri_for_action('admin/users/edit', object.comment_user_id) %]">[% loc('edit user') %]</a>
+ <a href="[% c.uri_for_action('admin/users/edit', [ object.comment_user_id ]) %]">[% loc('edit user') %]</a>
[% END %]
</p>
@@ -161,7 +161,7 @@
</p>
</div>
<p>
- <input type="checkbox" id="fetch_all_problems" name="fetch_all_problems"[% ' checked' IF object.get_extra_metadata('fetch_all_problems') %]>
+ <input type="checkbox" id="fetch_all_problems" name="extra[fetch_all_problems]"[% ' checked' IF object.get_extra_metadata('fetch_all_problems') %]>
<label for="fetch_all_problems" class="inline">[% loc('Always fetch all problems') %]</label>
</p>
</div>
diff --git a/templates/web/base/admin/category-checkboxes.html b/templates/web/base/admin/category-checkboxes.html
index eacd1a398..cf9530f22 100644
--- a/templates/web/base/admin/category-checkboxes.html
+++ b/templates/web/base/admin/category-checkboxes.html
@@ -1,12 +1,4 @@
-<fieldset>
- <legend>
- [% IF hint %]
- <div class="admin-hint">
- <p>[% hint %]</p>
- </div>
- [% END %]
- [% loc('Categories:') %]
- </legend>
+[% BLOCK checkboxes %]
<ul class="no-bullets no-margin">
<li>
[% loc('Select:') %]
@@ -18,8 +10,31 @@
<label class="inline" title="[% contact.email | html %]">
<input type="checkbox" name="contacts[[% contact.id %]]" [% 'checked' IF contact.active %]/>
[% contact.category %]
+ [% IF contact.group.size > 1 %]<small>([% contact.group.join('; ') | html %])</small>[% END %]
</label>
</li>
[% END %]
</ul>
+[% END %]
+<fieldset>
+ <legend>
+ [% IF hint %]
+ <div class="admin-hint">
+ <p>[% hint %]</p>
+ </div>
+ [% END %]
+ [% loc('Categories:') %]
+ </legend>
+
+ [% IF category_groups %]
+ [% FOR group IN category_groups %]
+ <h3>[% ( group.name OR loc('No Group') ) | html %]</h3>
+ [% IF group.name == loc("Multiple Groups") %]
+ <small>[% loc('These categories appear in more than one group:') %]</small>
+ [% END %]
+ [% INCLUDE checkboxes contacts=group.categories %]
+ [% END %]
+ [% ELSE %]
+ [% INCLUDE checkboxes contacts=contacts %]
+ [% END %]
</fieldset>
diff --git a/templates/web/base/admin/config_page.html b/templates/web/base/admin/config_page.html
index 8e8d562ff..a534292be 100644
--- a/templates/web/base/admin/config_page.html
+++ b/templates/web/base/admin/config_page.html
@@ -51,7 +51,12 @@ running version <strong>[% git_version || 'unknown' %]</strong>.
[% INCLUDE just_value value="ALLOWED_COBRANDS" conf = allowed_conf %]
<tr>
<td>Web templates</td>
-<td colspan=2>[% c.cobrand.path_to_web_templates.join('<br>') %]</td>
+<td colspan=2>
+ [% FOR path IN c.cobrand.path_to_web_templates %]
+ [% path %]
+ [% IF NOT loop.last %]<br>[% END %]
+ [% END %]
+</td>
</tr>
[% INCLUDE with_cobrand value="MAP_TYPE" cob=c.cobrand.map_type %]
[% INCLUDE with_cobrand value="EXAMPLE_PLACES"
@@ -117,7 +122,7 @@ running version <strong>[% git_version || 'unknown' %]</strong>.
[% INCLUDE just_value value="EMAIL_DOMAIN" %]
[% INCLUDE with_cobrand value="CONTACT_NAME" cob=c.cobrand.contact_name %]
[% INCLUDE with_cobrand value="CONTACT_EMAIL" cob=c.cobrand.contact_email %]
-[% INCLUDE just_value value="DO_NOT_REPLY_EMAIL" %]
+[% INCLUDE with_cobrand value="DO_NOT_REPLY_EMAIL" cob=c.cobrand.do_not_reply_email %]
[% INCLUDE subsection heading="Development" %]
[% INCLUDE just_value value="STAGING_SITE" %]
diff --git a/templates/web/base/admin/council_contacts.txt b/templates/web/base/admin/council_contacts.txt
index f11615789..2622f3fc2 100644
--- a/templates/web/base/admin/council_contacts.txt
+++ b/templates/web/base/admin/council_contacts.txt
@@ -1,4 +1,4 @@
-[% WHILE ( contact = contacts.next ) -%]
+[% FOR contact IN contacts -%]
[%- NEXT IF contact.state != 'confirmed' %]
[% contact.category_display %] [% contact.email %]
[%- END %]
diff --git a/templates/web/base/admin/defecttypes/list.html b/templates/web/base/admin/defecttypes/list.html
index ffff89eff..5730710d9 100644
--- a/templates/web/base/admin/defecttypes/list.html
+++ b/templates/web/base/admin/defecttypes/list.html
@@ -10,10 +10,9 @@
</tr>
</thead>
<tbody>
- [% PROCESS 'defect_type/format.html' %]
[% FOR d IN defect_types %]
<tr>
- <td> [% defect_type_format(defect_type=d) %] </td>
+ <td> [% d.name | html %] </td>
<td> [% d.description | html %] </td>
<td>
[% UNLESS d.contacts.size %]
diff --git a/templates/web/base/admin/exordefects/index.html b/templates/web/base/admin/exordefects/index.html
deleted file mode 100644
index 65b2aa486..000000000
--- a/templates/web/base/admin/exordefects/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-[% INCLUDE 'admin/header.html' title=('Download Exor RDI') -%]
-
-[% IF error_message %]
- <h2>Error</h2>
- <p>[% error_message %]</p>
-[% END %]
-
-<form method="get" action="[% c.uri_for('download') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
- <div class="filters">
- <p>
- <label for="start_date">[% ('Start Date:') %]</label><input type="date" class="form-control"
- name="start_date" id="start_date"
- value="[% start_date ? start_date.strftime( '%Y-%m-%d') : '' | html %]" />
- </p>
-
- <p>
- <label for="end_date">[% ('End Date:') %]</label><input type="date" class="form-control"
- name="end_date" id="end_date" size="5"
- value="[% end_date ? end_date.strftime( '%Y-%m-%d') : '' | html %]" />
- </p>
-
- <p>
- <label for="user_id">[% ('Inspector:') %]</label>
- <select class="form-control" id='user_id' name='user_id'>
- <option value=''>[% ('All inspectors') %]</option>
- [% FOR inspector IN inspectors %]
- <option value="[% inspector.id %]" [% 'selected' IF user_id == inspector.id %]>[% inspector.name %] ([% inspector.get_extra_metadata('initials') %])</option>
- [% END %]
- </select>
- </p>
- </div>
-
- <p>
- <input type="submit" class="btn" size="30" value="Download RDI file" />
- </p>
-</form>
-
-
-[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/extra-metadata-form.html b/templates/web/base/admin/extra-metadata-form.html
index 4fc5d8e3f..9b8e4909f 100644
--- a/templates/web/base/admin/extra-metadata-form.html
+++ b/templates/web/base/admin/extra-metadata-form.html
@@ -1,91 +1,11 @@
-<ul class="js-metadata-items">
- [% FOR meta IN metas.merge([{}]) %]
- <li class="js-metadata-item [% IF loop.last %]hidden-js js-metadata-item-template[% END %]" data-index="[% loop.index %]">
- <button class="btn btn--small js-metadata-item-remove hidden-nojs">[% loc('Remove field') %]</button>
+<div class="extra-metadata-form js-metadata-items">
+ [% FOR meta IN metas %]
+ [% INCLUDE 'admin/extra-metadata-item.html' i=loop.index collapsed=1 %]
+ [% END %]
+</div>
- <div class="admin-hint"><p>[% loc('The ordering of this field on the report page. Fields are shown in ascending order according to this value.') %]</p></div>
- <label>
- [% loc('Order') %]
- <input name="metadata[[% loop.index %]].order" data-field-name="order" type=text value="[% meta.order OR 0 | html %]">
- </label>
+<div class="hidden-js" id="js-template-extra-metadata-item">
+ [% INCLUDE 'admin/extra-metadata-item.html' meta={} i=9999 collapsed=0 %]
+</div>
- <div class="admin-hint"><p>[% loc('Whether the field is displayed to the user, included as a hidden field and automatically populated, or set by the server upon Open311 submission. This field is usually set automatically.') %]</p></div>
- <label>
- [% loc('Automated') %]
- <select name="metadata[[% loop.index %]].automated" data-field-name="automated">
- <option value="" [% meta.automated == '' ? 'selected' : '' %]></option>
- <option value="server_set" [% meta.automated == 'server_set' ? 'selected' : '' %]>[% loc('Server Set') %]</option>
- <option value="hidden_field" [% meta.automated == 'hidden_field' ? 'selected' : '' %]>[% loc('Hidden Field') %]</option>
- </select>
- </label>
-
- <div class="admin-hint"><p>[% loc('The code used to store this field value in the database. e.g. <code>address</code> would be available as <code>problem.extra.address</code> in the templates.') %]</p></div>
- <label>
- [% loc('Code') %]
- <input name="metadata[[% loop.index %]].code" data-field-name="code" type=text value="[% meta.code | html %]">
- </label>
-
- <div class="admin-hint"><p>[% loc('Whether the user is required to provide a value for this field.') %]</p></div>
- <label>
- [% loc('Required') %]
- <input name="metadata[[% loop.index %]].required" data-field-name="required" type=checkbox [% meta.required == 'true' ? 'checked' : '' %]>
- </label>
-
- <div class="admin-hint"><p>[% loc('If ticked the user won’t see an input field, just the ‘Description’ text.') %]</p></div>
- <label>
- [% loc('Notice') %]
- <input name="metadata[[% loop.index %]].notice" data-field-name="notice" type=checkbox [% meta.variable == 'false' ? 'checked' : '' %]>
- </label>
-
- <div class="admin-hint"><p>[% loc('The field name as shown to the user on the report form.') %]</p></div>
- <label>
- [% loc('Description') %]
- <input name="metadata[[% loop.index %]].description" data-field-name="description" type=text value="[% meta.description | html %]">
- </label>
-
- <div class="admin-hint"><p>[% loc('Can be used to display extra text to the user alongside the field. The default template does not show this (<code>meta.datatype_description</code>), you must add it in <code>category_extras_fields.html</code>') %]</p></div>
- <label>
- [% loc('Hint') %]
- <input name="metadata[[% loop.index %]].datatype_description" data-field-name="datatype_description" type=text value="[% meta.datatype_description | html %]">
- </label>
-
- <div class="admin-hint"><p>[% loc('The type of input field to show to the user. <strong>Text</strong> is a simple text field, <strong>List</strong> is a drop-down selection.') %]</p></div>
- <label>
- [% loc('Type') %]
- <select name="metadata[[% loop.index %]].datatype" data-field-name="datatype" class="js-metadata-item-type">
- <option value="string" [% meta.datatype == 'string' ? 'selected' : '' %]>[% loc('String') %]</option>
- <option value="singlevaluelist" [% meta.datatype == 'singlevaluelist' ? 'selected' : '' %]>[% loc('List') %]</option>
- </select>
- </label>
-
- <div class="js-metadata-options">
- <div class="admin-hint"><p>[% loc('For each option, <strong>Key</strong> is the value which is stored in the database for that option and <strong>Name</strong> is the value displayed to the user.') %]</p></div>
- [% loc('Options') %]<span class="hidden-js"> [% loc('(ignored if type is "String")') %]</span>
- <ul>
- [% outer_loop = loop %]
- [% values = meta.values OR [] %]
- [% FOREACH option IN values.merge([{}]) %]
- [%# the .merge() call is so there's an empty one on the end %]
- <li class="js-metadata-option [% IF loop.last %]hidden-js js-metadata-option-template[% END %]">
- <label>
- [% loc('Key') %]
- <input class="js-metadata-option-key" name="metadata[[% outer_loop.index %]].values[[% loop.index %]].key" type="text" value="[% option.key | html %]">
- </label>
- <label>
- [% loc('Name') %]
- <input class="js-metadata-option-name" name="metadata[[% outer_loop.index %]].values[[% loop.index %]].name" type="text" value="[% option.name | html %]">
- </label>
- <button class="btn btn--small js-metadata-option-remove hidden-nojs">[% loc('Remove') %]</button>
- </li>
- [% END %]
- <li class="hidden-nojs">
- <button class="btn btn--small js-metadata-option-add">[% loc('Add option') %]</button>
- </li>
- </ul>
- </div>
- </li>
- [%- END %]
- <li class="hidden-nojs">
- <button class="btn btn--small js-metadata-item-add">[% loc('Add field') %]</button>
- </li>
-</ul>
+<button type="button" class="btn btn--small js-metadata-item-add hidden-nojs">[% loc('Add field') %]</button>
diff --git a/templates/web/base/admin/extra-metadata-item.html b/templates/web/base/admin/extra-metadata-item.html
new file mode 100644
index 000000000..66cb6f79c
--- /dev/null
+++ b/templates/web/base/admin/extra-metadata-item.html
@@ -0,0 +1,110 @@
+[%
+SET behaviour = '';
+DEFAULT behaviour = 'server' IF meta.automated == 'server_set';
+DEFAULT behaviour = 'hidden' IF meta.automated == 'hidden_field';
+DEFAULT behaviour = 'notice' IF meta.variable == 'false';
+DEFAULT behaviour = 'question';
+~%]
+
+<fieldset class="extra-metadata-item js-metadata-item" data-i="[% i %]">
+ <legend class="visuallyhidden">Extra data field [% i %]</legend>
+
+ <header class="extra-metadata-item__header hidden-nojs">
+ <div class="js-metadata-item-header-grab extra-metadata-item__header__grab" aria-label="Drag to reorder"></div>
+ <button type="button" class="js-metadata-item-header-title extra-metadata-item__header__title" data-default="[% loc('New field') %]" data-toggle-visibility="#metadata-fieldset-[% i %]">
+ [%~ IF meta.code ~%]
+ <strong>[% meta.code | html %]</strong>
+ / [% behaviour %]
+ [% IF meta.description %] / [% meta.description.substr(0, 50) | html %][% END %]
+ [%~ ELSE ~%]
+ <strong>[% loc('New field') %]</strong>
+ [%~ END ~%]
+ </button>
+ <button type="button" class="js-metadata-item-remove extra-metadata-item__header__remove">[% loc('Remove field') %]</button>
+ </header>
+
+ <div class="extra-metadata-item__body [% IF collapsed %]hidden-js[% END %]" id="metadata-fieldset-[% i %]">
+
+ <div class="form-group">
+ <label for="metadata-[% i %]-code">[% loc('Code') %]</label>
+ <span class="form-hint" id="metadata-[% i %]-code-hint">[% loc('The code used to store this field value in the database.') %]</span>
+ <input class="form-control" name="metadata[[% i %]].code" id="metadata-[% i %]-code" aria-describedby="metadata-[% i %]-code-hint" type=text value="[% meta.code | html %]">
+ </div>
+
+ <fieldset>
+ <legend>[% loc('Behaviour') %]</legend>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="metadata[[% i %]].behaviour" id="metadata-[% i %]-behaviour-question" value="question" data-show="#metadata-[% i %]-description-group, #metadata-[% i %]-description-label-question, #metadata-[% i %]-datatype-group, #metadata-[% i %]-required-group, #metadata-[% i %]-protected-group" data-hide="#metadata-[% i %]-description-label-notice, #metadata-[% i %]-disabled-group"[% ' checked' IF behaviour == 'question' %]>
+ <label for="metadata-[% i %]-behaviour-question">[% loc('Extra question shown to user') %]</label>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="metadata[[% i %]].behaviour" id="metadata-[% i %]-behaviour-notice" value="notice" data-show="#metadata-[% i %]-description-group, #metadata-[% i %]-description-label-notice, #metadata-[% i %]-protected-group, #metadata-[% i %]-disabled-group" data-hide="#metadata-[% i %]-description-label-question, #metadata-[% i %]-datatype-group, #metadata-[% i %]-required-group"[% ' checked' IF behaviour == 'notice' %]>
+ <label for="metadata-[% i %]-behaviour-notice">[% loc('Notice shown to user') %]</label>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="metadata[[% i %]].behaviour" id="metadata-[% i %]-behaviour-hidden" value="hidden" data-show="#metadata-[% i %]-protected-group" data-hide="#metadata-[% i %]-description-group, #metadata-[% i %]-datatype-group, #metadata-[% i %]-required-group, #metadata-[% i %]-disabled-group"[% ' checked' IF behaviour == 'hidden' %]>
+ <label for="metadata-[% i %]-behaviour-hidden">[% loc('Hidden data in reporting form') %]</label>
+ </div>
+ <div class="form-check form-check--inline">
+ <input type="radio" name="metadata[[% i %]].behaviour" id="metadata-[% i %]-behaviour-server" value="server" data-show="#metadata-[% i %]-protected-group" data-hide="#metadata-[% i %]-description-group, #metadata-[% i %]-datatype-group, #metadata-[% i %]-required-group, #metadata-[% i %]-disabled-group"[% ' checked' IF behaviour == 'server' %]>
+ <label for="metadata-[% i %]-behaviour-server">[% loc('Internal data set by Open311') %]</label>
+ </div>
+ </fieldset>
+
+ <div class="form-group js-sort-order">
+ <label for="metadata-[% i %]-order">[% loc('Order') %]</label>
+ <input class="form-control" name="metadata[[% i %]].order" id="metadata-[% i %]-order" type=text value="[% meta.order OR 0 | html %]">
+ </div>
+
+ <div class="form-group hidden-js" id="metadata-[% i %]-description-group">
+ <label for="metadata-[% i %]-description" id="metadata-[% i %]-description-label-question" class="[% 'hidden-js' UNLESS behaviour == 'question' %]">[% loc('Question text') %]</label>
+ <label for="metadata-[% i %]-description" id="metadata-[% i %]-description-label-notice" class="[% 'hidden-js' UNLESS behaviour == 'notice' %]">[% loc('Notice text') %]</label>
+ <textarea class="form-control" name="metadata[[% i %]].description" id="metadata-[% i %]-description" rows="2">[% meta.description | html %]</textarea>
+ </div>
+
+ <div class="hidden-js" id="metadata-[% i %]-datatype-group">
+ <div class="form-group">
+ <label for="metadata-[% i %]-datatype">[% loc('Display as') %]</label>
+ <select class="form-control" name="metadata[[% i %]].datatype" id="metadata-[% i %]-datatype">
+ <option value="string" data-hide="#metadata-[% i %]-options-group" [% 'selected' IF meta.datatype == 'string' %]>[% loc('Text field') %]</option>
+ <option value="singlevaluelist" data-show="#metadata-[% i %]-options-group" [% 'selected' IF meta.datatype == 'singlevaluelist' %]>[% loc('Drop-down list') %]</option>
+ </select>
+ </div>
+
+ <div class="hidden-js" id="metadata-[% i %]-options-group">
+ <p class="label">[% loc('Options') %]</p>
+ <div class="js-metadata-options">
+ [% SET options = meta.item('values') ? meta.values : [] %]
+ [% FOR option IN options %]
+ [% INCLUDE 'admin/extra-metadata-option.html' option=option i=i j=loop.index %]
+ [% END %]
+ </div>
+
+ <div class="hidden-js"[% IF i==9999 %] id="js-template-extra-metadata-option"[% END %]>
+ [% INCLUDE 'admin/extra-metadata-option.html' option={} i=i j=8888 %]
+ </div>
+
+ <button type="button" class="btn btn--small js-metadata-option-add hidden-nojs">[% loc('Add option') %]</button>
+ </div>
+ </div>
+
+ <p class="form-check hidden-js" id="metadata-[% i %]-required-group">
+ <input type="checkbox" name="metadata[[% i %]].required" value="1" id="metadata-[% i %]-required" aria-describedby="metadata-[% i %]-required-hint" [% ' checked' IF meta.required == 'true' %]>
+ <label for="metadata-[% i %]-required">[% loc('Required') %]</label>
+ <span class="form-hint" id="metadata-[% i %]-required-hint">[% loc('Prevent user from submitting the form until this field is filled in.') %]</span>
+ </p>
+
+ <p class="form-check hidden-js" id="metadata-[% i %]-disabled-group">
+ <input type="checkbox" name="metadata[[% i %]].disable_form" value="1" id="metadata-[% i %]-disable_form" aria-describedby="metadata-[% i %]-disable_form-hint" [% ' checked' IF meta.disable_form == 'true' %]>
+ <label for="metadata-[% i %]-disable_form">[% loc('Disable form when this category is selected') %]</label>
+ <span class="form-hint" id="metadata[[% i %]]-disable_form-hint">[% loc('If ticked, the form will be disabled and this item’s notice text will be displayed.') %]</span>
+ </p>
+
+ <p class="form-check hidden-js" id="metadata-[% i %]-protected-group">
+ <input type="checkbox" name="metadata[[% i %]].protected" value="1" id="metadata-[% i %]-protected" aria-describedby="metadata-[% i %]-protected-hint" [% ' checked' IF meta.protected == 'true' %]>
+ <label for="metadata-[% i %]-protected">[% loc('Protect from Open311 changes') %]</label>
+ <span class="form-hint" id="metadata[[% i %]]-protected-hint">[% loc('If ticked, this extra data will not be edited or deleted by the Open311 population script.') %]</span>
+ </p>
+
+ </div>
+</fieldset>
diff --git a/templates/web/base/admin/extra-metadata-option.html b/templates/web/base/admin/extra-metadata-option.html
new file mode 100644
index 000000000..360dfb208
--- /dev/null
+++ b/templates/web/base/admin/extra-metadata-option.html
@@ -0,0 +1,29 @@
+<fieldset class="extra-metadata-option js-metadata-option">
+ <legend class="visuallyhidden">Option [% j %]</legend>
+
+ <div class="row">
+ <div class="col">
+ <label for="metadata-[% i %]-values-[% j %]-key">[% loc('Internal key') %]</label>
+ <input type="text" class="form-control" name="metadata[[% i %]].values[[% j %]].key" id="metadata-[% i %]-values-[% j %]-key" value="[% option.key | html %]">
+ </div>
+ <div class="col">
+ <label for="metadata-[% i %]-values-[% j %]-name">[% loc('Displayed label') %]</label>
+ <input type="text" class="form-control" name="metadata[[% i %]].values[[% j %]].name" id="metadata-[% i %]-values-[% j %]-name" value="[% option.name | html %]">
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <p class="form-check">
+ <input type="checkbox" name="metadata[[% i %]].values[[% j %]].disable" value="1" id="metadata-[% i %]-values-[% j %]-disable" data-toggle-visibility="#js-disable-form-message-box-[% i %]-[% j %]" [% ' checked' IF option.disable %]>
+ <label for="metadata-[% i %]-values-[% j %]-disable">[% loc('Disable form when this option is selected') %]</label>
+ </p>
+ <p class="form-group [% 'hidden-js' IF NOT option.disable %]" id="js-disable-form-message-box-[% i %]-[% j %]">
+ <label for="disabled-message-[% i %]-[% j %]">[% loc('Message to show when form is disabled (HTML permitted)') %]</label>
+ <textarea id="disabled-message-[% i %]-[% j %]" name="metadata[[% i %]].values[[% j %]].disable_message" class="form-control">[% option.disable_message OR meta.datatype_description | html %]</textarea>
+ </p>
+ </div>
+ <div class="col">
+ <button type="button" class="js-metadata-option-remove">[% loc('Remove option') %]</button>
+ </div>
+ </div>
+</fieldset>
diff --git a/templates/web/base/admin/index.html b/templates/web/base/admin/index.html
index 8691dbcf8..88c7ff959 100644
--- a/templates/web/base/admin/index.html
+++ b/templates/web/base/admin/index.html
@@ -20,34 +20,40 @@ and to receive notices of updates.
</p>
[% END %]
-<div class="admin-index-search form-txt-submit-box clearfix">
+<div class="admin-index-search clearfix">
<form method="get" action="[% c.uri_for('reports') %]" accept-charset="utf-8">
- <p><label for="search_reports">[% loc('Search Reports') %]</label>
+ <label for="search_reports">[% loc('Search Reports') %]</label>
+ <div class="form-txt-submit-box">
<input type="text" class="form-control" name="search" size="30" id="search_reports" value="[% searched | html %]">
<input type="submit" class="btn" value="[% loc('Go') %]">
+ </div>
</form>
<form method="get" action="[% c.uri_for('users') %]" accept-charset="utf-8">
- <p><label for="search_users">[% loc('Search Users') %]</label>
+ <label for="search_users">[% loc('Search Users') %]</label>
+ <div class="form-txt-submit-box">
<input type="text" class="form-control" name="search" size="30" id="search_users" value="[% searched | html %]">
<input type="submit" class="btn" value="[% loc('Go') %]">
+ </div>
</form>
[% IF c.user.is_superuser %]
- <form method="get" action="[% c.uri_for('bodies') %]">
- <label for="search_body">[% loc('Edit body details') %]</label>
- <select class="form-control" id="search_body" name="body">
- [% FOREACH body IN bodies %]
- [%- SET id = body.id %]
- <option[% IF body.deleted %] class="adminhidden"[% END %] value="[% body.id %]">
- [% body.name | html %]
- [%- IF body.parent %], [% body.parent.name | html %][% END -%]
- </option>
- [% END %]
- </select>
- <input type="submit" class="btn" value="[% loc('Go') %]">
- </form>
+<form method="get" action="[% c.uri_for('bodies') %]">
+ <label for="search_body">[% loc('Edit body details') %]</label>
+ <div class="form-txt-submit-box">
+ <select class="form-control" id="search_body" name="body">
+ [% FOREACH body IN bodies %]
+ [%- SET id = body.id %]
+ <option[% IF body.deleted %] class="adminhidden"[% END %] value="[% body.id %]">
+ [% body.name | html %]
+ [%- IF body.parent %], [% body.parent.name | html %][% END -%]
+ </option>
+ [% END %]
+ </select>
+ <input type="submit" class="btn" value="[% loc('Go') %]">
+ </div>
+</form>
[% END %]
</div>
@@ -68,13 +74,4 @@ and to receive notices of updates.
</table>
[% END %]
-<h2>[% loc('Stats') %]</h2>
-[% INCLUDE 'status/stats.html' admin_include_users=1 %]
-
-[% IF c.cobrand.admin_show_creation_graph -%]
- <p>
- <a href="[% c.config.BASE_URL %]/fms-live-creation.png" class="admin-offsite-link">[% loc('Graph of problem creation by status over time') %]</a>
- </p>
-[% END -%]
-
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/list_updates.html b/templates/web/base/admin/list_updates.html
index b23cd7ca3..e8abdddad 100644
--- a/templates/web/base/admin/list_updates.html
+++ b/templates/web/base/admin/list_updates.html
@@ -41,7 +41,7 @@
</small></td>
<td rowspan=2>
[% IF c.user.has_permission_to('report_edit', update.problem.bodies_str_ids) %]
- <a href="[% c.uri_for( 'update_edit', update.id ) %]">[% loc('Edit') %]</a>
+ <a href="[% c.uri_for_action( 'admin/update_edit', [ update.id ] ) %]">[% loc('Edit') %]</a>
[% END %]
</td>
</tr>
diff --git a/templates/web/base/admin/manifesttheme/form.html b/templates/web/base/admin/manifesttheme/form.html
new file mode 100644
index 000000000..6d02487a6
--- /dev/null
+++ b/templates/web/base/admin/manifesttheme/form.html
@@ -0,0 +1,71 @@
+[% INCLUDE 'admin/header.html' title=loc('Theme') -%]
+
+<form method="post" enctype="multipart/form-data">
+ <div class="admin-hint">
+ <p>[% loc("The <strong>name</strong> is a string that represents the name of the web application as it is usually displayed to the user (e.g., amongst a list of other applications, or as a label for an icon).") %]</p>
+ </div>
+ [% form.field('name').render | safe %]
+
+ <div class="admin-hint">
+ <p>[% loc("The <strong>short name</strong> is a string that represents the name of the web application displayed to the user if there is not enough space to display name (e.g., as a label for an icon on the phone home screen).") %]</p>
+ </div>
+ [% form.field('short_name').render | safe %]
+
+ <div class="admin-hint">
+ <p>[% loc("The <strong>theme colour</strong> defines the default theme colour for the application. This sometimes affects how the OS displays the site (e.g., on Android's task switcher, the theme colour surrounds the site). Colours should be specified with CSS syntax, e.g. <strong><code>#ff00ff</code></strong> or <strong><code>rgb(255, 0, 255)</code></strong> or a named colour like <strong><code>fuchsia</code></strong>.") %]</p>
+ </div>
+ [% form.field('theme_colour').render | safe %]
+
+ <div class="admin-hint">
+ <p>[% loc("The <strong>background colour</strong> defines a placeholder background colour for the application splash screen before it has loaded. Colours should be specified with CSS syntax, e.g. <strong><code>#ff00ff</code></strong> or <strong><code>rgb(255, 0, 255)</code></strong> or a named colour like <strong><code>fuchsia</code></strong>.") %]</p>
+ </div>
+ [% form.field('background_colour').render | safe %]
+
+ [% IF show_all %]
+ [% form.field('cobrand').render | safe %]
+ [% ELSE %]
+ <input type=hidden name=cobrand value='[% c.cobrand.moniker %]' />
+ [% END %]
+
+ <table>
+ <thead>
+ <tr>
+ <th>Icon</th>
+ <th>Size</th>
+ <th>Delete?</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOREACH icon IN editing_manifest_theme.icons %]
+ <tr>
+ <td><img src="[% icon.src %]" /></td>
+ <td class="icon-size">[% icon.sizes %]</td>
+ <td><input type=checkbox name=delete_icon value='[% icon.src %]' /></td>
+ </tr>
+ [% END %]
+ <tr>
+ <td colspan=3>
+ <div class="admin-hint">
+ <p>[% loc("The <strong>icons</strong> are used when the application is installed to the user's home screen. Icons must be <strong>square</strong>, with <strong>512x512</strong>px and <strong>192x192</strong>px being the most common sizes.") %]</p>
+ </div>
+ [% form.field('icon').render | safe %]
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p>
+ <input class="btn" type="submit" name="submit" value="[% loc('Save changes') %]">
+ </p>
+ [% IF form.item.id %]
+ <p>
+ <input class="btn-danger" type="submit" name="delete_theme" value="[% loc('Delete theme') %]" data-confirm="[% loc('Are you sure?') %]">
+ </p>
+ [% END %]
+</form>
+
+[% IF show_all %]
+ <p><a href="[% c.uri_for(c.controller.action_for('list')) %]">Return to themes list</a></p>
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/manifesttheme/index.html b/templates/web/base/admin/manifesttheme/index.html
new file mode 100644
index 000000000..df94c394f
--- /dev/null
+++ b/templates/web/base/admin/manifesttheme/index.html
@@ -0,0 +1,35 @@
+[% INCLUDE 'admin/header.html' title=loc('Themes') %]
+
+<table>
+ <thead>
+ <tr>
+ <th> [% loc('Cobrand') %] </th>
+ <th> [% loc('Name') %] </th>
+ <th> [% loc('Short Name') %] </th>
+ <th> [% loc('Background Colour') %] </th>
+ <th> [% loc('Theme Colour') %] </th>
+ <th> &nbsp; </th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOR theme IN rs.all %]
+ <tr>
+ <td>[% theme.cobrand %]</td>
+ <td>[% theme.name %]</td>
+ <td>[% theme.short_name %]</td>
+ <td>[% theme.background_colour %]</td>
+ <td>[% theme.theme_colour %]</td>
+ <td> <a href="[% c.uri_for(c.controller.action_for('edit'), [theme.cobrand]) %]" class="btn">[% loc('Edit') %]</a> </td>
+ </tr>
+ [% END %]
+ </tbody>
+</table>
+
+
+
+<p>
+ <a href="[% c.uri_for(c.controller.action_for('create')) %]">[% loc('Create') %]</a>
+ </p>
+
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/problem_row.html b/templates/web/base/admin/problem_row.html
index 99142af4e..8d74fec13 100644
--- a/templates/web/base/admin/problem_row.html
+++ b/templates/web/base/admin/problem_row.html
@@ -23,7 +23,7 @@
[% PROCESS value_or_nbsp value=problem.category_display %]
<br>[%- IF edit_body_contacts -%]
[% FOR body IN problem.bodies.values %]
- <a href="[% c.uri_for('body', body.id ) %]">[% PROCESS value_or_nbsp value=body.name %]</a>
+ <a href="[% c.uri_for_action('admin/bodies/edit', [ body.id ] ) %]">[% PROCESS value_or_nbsp value=body.name %]</a>
[% END %]
[%- ELSE -%]
[%- PROCESS value_or_nbsp value=problem.bodies_str -%]
@@ -40,7 +40,7 @@
</small></td>
<td>
[% IF c.user.has_permission_to('report_edit', problem.bodies_str_ids) %]
- <a href="[% c.uri_for( 'report_edit', problem.id ) %]">[% loc('Edit') %]</a>
+ <a href="[% c.uri_for_action( '/admin/reports/edit', [ problem.id ] ) %]">[% loc('Edit') %]</a>
[% END %]
</td>
</tr>
diff --git a/templates/web/base/admin/report-category.html b/templates/web/base/admin/report-category.html
index 0416d71c0..e76106f7f 100644
--- a/templates/web/base/admin/report-category.html
+++ b/templates/web/base/admin/report-category.html
@@ -1,14 +1,15 @@
-<select class="form-control" name="category" id="category">
+[%~ IF NOT select_name %]
+ [%~ select_name = 'category' %]
+[%~ END %]
+[%~ BLOCK category_option ~%]
+<option value="[% cat.category | html %]"[% ' selected' IF problem.category == cat.category %]>[% cat.category_display | html %]</option>
+[%~ END ~%]
+
+<select class="form-control" name="[% select_name %]" id="[% select_name %]">
[% IF NOT problem.category OR NOT categories_hash.${problem.category} %]
<optgroup label="[% loc('Existing category') %]">
<option selected value="[% problem.category | html %]">[% (problem.category_display OR '-') | html %]</option>
</optgroup>
[% END %]
- [% IF category_options.size %]
- <optgroup label="[% loc('Available categories') %]">
- [% FOREACH cat IN category_options %]
- <option value="[% cat.category | html %]"[% ' selected' IF problem.category == cat.category %]>[% cat.category_display | html %]</option>
- [% END %]
- </optgroup>
- [% END %]
+ [%~ INCLUDE 'report/new/_category_select.html' ~%]
</select>
diff --git a/templates/web/base/admin/report_blocks.html b/templates/web/base/admin/report_blocks.html
index 4c52b14bb..4c679e3b8 100644
--- a/templates/web/base/admin/report_blocks.html
+++ b/templates/web/base/admin/report_blocks.html
@@ -47,3 +47,7 @@ SET state_groups = c.cobrand.state_groups_admin;
</span>
[% END %]
[% END %]
+
+[% BLOCK status_message %]
+ <p><em>[% status_message %]</em></p>
+[% END %]
diff --git a/templates/web/base/admin/report_edit.html b/templates/web/base/admin/reports/edit.html
index e38932d7f..d2b866d01 100644
--- a/templates/web/base/admin/report_edit.html
+++ b/templates/web/base/admin/reports/edit.html
@@ -7,7 +7,7 @@
PROCESS 'admin/report_blocks.html'
-%]
-[% map_html %]
+[% map_html | safe %]
</div>
<div id="map_sidebar">
@@ -16,7 +16,7 @@
<div id="side">
-<form method="post" action="[% c.uri_for( 'report_edit', problem.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+<form method="post" action="[% c.uri_for_action( '/admin/reports/edit', [ problem.id ] ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
<input type="hidden" name="token" value="[% csrf_token %]" >
<input type="hidden" name="submit" value="1" >
@@ -57,7 +57,7 @@ class="admin-offsite-link">[% problem.latitude %], [% problem.longitude %]</a>
[% IF problem.bodies_str %]
[% FOREACH body IN problem.bodies.values %]
[% SET body_printed = 1 %]
- <a href="[% c.uri_for('body', body.id) %]">[% body.name | html %]</a>
+ <a href="[% c.uri_for_action('admin/bodies/edit', [ body.id ]) %]">[% body.name | html %]</a>
[%- ',' IF NOT loop.last %]
[% END %]
[% IF NOT body_printed %]
@@ -81,12 +81,17 @@ class="admin-offsite-link">[% problem.latitude %], [% problem.longitude %]</a>
[% IF problem.send_method_used %]
([% problem.send_method_used %])
[% END %]
- [% IF problem.state == 'confirmed' AND problem.whensent %]
+ [% IF problem.state == 'confirmed' AND problem.whensent AND NOT c.cobrand.disable_resend_button %]
<input data-confirm="[% loc('Are you sure?') %]" class="btn" type="submit" name="resend" value="[% loc('Resend report') %]">
[% ELSIF NOT problem.whensent %]
<input type="submit" class="btn" name="mark_sent" value="[% loc('Mark as sent') %]">
[% END %]
</li>
+[% IF c.user.is_superuser AND problem.send_fail_count > 0 %]
+<li class="sm">[% loc('Send Fail Count:') %] [% problem.send_fail_count %]</li>
+<li class="sm">[% loc('Last failure:') %] [% PROCESS format_time time=problem.send_fail_timestamp %]</li>
+<li class="sm truncate_height">[% loc('Reason:') %] [% problem.send_fail_reason | html %]</li>
+[% END %]
<li class="sm">[% loc('Last update:') %] [% PROCESS format_time time=problem.lastupdate %]</li>
<li>[% loc('Alerts:') %] [% alert_count %]</li>
<li>[% loc('Service:') %] [% problem.service OR '<em>' _ loc('None') _ '</em>' %]</li>
@@ -111,7 +116,7 @@ class="admin-offsite-link">[% problem.latitude %], [% problem.longitude %]</a>
</ul>
</div>
-[% status_message %]
+[% INCLUDE status_message %]
<ul class="plain-list">
<li><label for='title'>[% loc('Subject:') %]</label>
diff --git a/templates/web/base/admin/reports.html b/templates/web/base/admin/reports/index.html
index 7d8fe9561..adbd50224 100644
--- a/templates/web/base/admin/reports.html
+++ b/templates/web/base/admin/reports/index.html
@@ -1,7 +1,7 @@
[% INCLUDE 'admin/header.html' title=loc('Search Reports') %]
[% PROCESS 'admin/report_blocks.html' %]
-<form method="get" action="[% c.uri_for('reports') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+<form method="get" action="[% c.uri_for_action('/admin/reports/index') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
<p><label for="search">[% loc('Search:') %]</label>
<input class="form-control" type="text" name="search" size="30" id="search" value="[% searched | html %]">
</form>
diff --git a/templates/web/base/admin/responsepriorities/edit.html b/templates/web/base/admin/responsepriorities/edit.html
index 02661fd14..b9074999f 100644
--- a/templates/web/base/admin/responsepriorities/edit.html
+++ b/templates/web/base/admin/responsepriorities/edit.html
@@ -1,57 +1,46 @@
[% INCLUDE 'admin/header.html' title=tprintf(loc('Response Priority for %s'), body.name) -%]
-[% rp = response_priority %]
-[% UNLESS rp.id %]<h3>[% loc('New priority') %]</h3>[% END %]
+[% UNLESS obj %]<h3>[% loc('New priority') %]</h3>[% END %]
-<form method="post"
- action="[% c.uri_for('', body.id, rp.id || 'new' ) %]"
- enctype="application/x-www-form-urlencoded"
- accept-charset="utf-8"
- class="validate">
+<form method="post" accept-charset="utf-8" class="validate">
- <p>
- <strong>[% loc('Name:') %] </strong>
- <input type="text" name="name" class="required form-control" size="30" value="[% rp.name | html %]">
- </p>
- <p>
- <strong>[% loc('Description:') %] </strong>
- <input type="text" name="description" class="form-control" size="30" value="[% rp.description | html %]">
- </p>
+ [% form.field('name').render | safe %]
+ [% form.field('description').render | safe %]
<div class="admin-hint">
<p>
[% loc('If this priority is passed to an external service (e.g. Exor/Confirm) enter the priority code to use with that service here.') %]
</p>
</div>
- <p>
- <strong>[% loc('External ID') %]:</strong>
- <input type="text" name="external_id" class="form-control" size="30" value="[% rp.external_id | html %]">
- </p>
+ [% form.field('external_id').render | safe %]
<div class="admin-hint">
<p>
[% loc('Select if this is the default priority') %]
</p>
</div>
- <p>
- <label>
- <input type="checkbox" name="is_default" is="is_deleted" value="1"[% ' checked' IF rp.is_default %]>
- [% loc('Default priority') %]
- </label>
- </p>
-
- [% INCLUDE 'admin/category-checkboxes.html' hint=loc('If you only want this priority to be an option for specific categories, pick them here. By default they will show for all categories.') %]
+ [% form.field('is_default').render | safe %]
+
+ <fieldset>
+ <legend>
+ <div class="admin-hint">
+ <p>
+ [% loc('If you only want this priority to be an option for specific categories, pick them here. By default they will show for all categories.') %]
+ </p>
+ </div>
+ [% loc('Categories:') %]
+ </legend>
+ [%# TODO Select all/none %]
+ [% form.field('contacts').render | safe %]
+ </fieldset>
+
+ [% form.field('deleted').render | safe %]
<p>
- <label>
- <input type="checkbox" name="deleted" id="deleted" value="1"[% ' checked' IF rp.deleted %]>
- [% loc('Flag as deleted') %]
- </label>
- </p>
- <p>
<input type="hidden" name="token" value="[% csrf_token %]" >
- <input type="submit" class="btn" name="Edit priorities" value="[% rp.id ? loc('Save changes') : loc('Create priority') %]" >
+ <input type="submit" class="btn" name="Edit priorities" value="[% obj ? loc('Save changes') : loc('Create priority') %]" >
</p>
+
</form>
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/responsepriorities/index.html b/templates/web/base/admin/responsepriorities/index.html
index 882a3c538..bb6324dbe 100644
--- a/templates/web/base/admin/responsepriorities/index.html
+++ b/templates/web/base/admin/responsepriorities/index.html
@@ -1,11 +1,55 @@
[% INCLUDE 'admin/header.html' title=loc('Response Priorities') -%]
-<ul>
- [% FOR body IN bodies %]
- <li>
- <a href="[% c.uri_for('', body.id) %]">[% body.name %]</a>
- </li>
- [% END %]
-</ul>
+<table>
+ <thead>
+ <tr>
+ <th> [% loc('Name') %] </th>
+ <th> [% loc('Description') %] </th>
+ <th> [% loc('Categories') %] </th>
+ <th> [% loc('Default') %] </th>
+ <th> &nbsp; </th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOR p IN response_priorities %]
+ [% IF c.user.is_superuser AND last_name != p.body.name %]
+ <tr>
+ <td colspan="5"><strong>[% p.body.name %]</strong></td>
+ </tr>
+ [% SET last_name = p.body.name %]
+ [% END %]
+ <tr [% 'class="is-deleted"' IF p.deleted %]>
+ <td> [% p.name | html %] </td>
+ <td> [% p.description | html %] </td>
+ <td>
+ [% UNLESS p.contacts.size %]
+ <em>[% loc('All categories') %]</em>
+ [% ELSE %]
+ [% FOR contact IN p.contacts %]
+ [% contact.category_display %][% ',' UNLESS loop.last %]
+ [% END %]
+ [% END %]
+ </td>
+ <td> [% IF p.is_default %]X[% END %]</td>
+ <td> <a href="[% c.uri_for(c.controller.action_for('edit'), [p.body_id, p.id]) %]" class="btn">[% loc('Edit') %]</a> </td>
+ </tr>
+ [% END %]
+ </tbody>
+</table>
+
+[% IF c.user.is_superuser %]
+<h3>[% loc('Create priority') %]</h3>
+<form>
+<select name="body_id">
+ [% FOR body IN bodies %]
+ <option value="[% body.id %]">[% body.name | html %]</option>
+ [% END %]
+</select>
+<input type="submit" value="[% loc('Go') %]">
+</form>
+
+[% ELSE %]
+<a href="[% c.uri_for(c.controller.action_for('create'), [c.user.from_body.id]) %]" class="btn">[% loc('New priority') %]</a>
+[% END %]
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/responsepriorities/list.html b/templates/web/base/admin/responsepriorities/list.html
deleted file mode 100644
index eedaccfdb..000000000
--- a/templates/web/base/admin/responsepriorities/list.html
+++ /dev/null
@@ -1,36 +0,0 @@
-[% INCLUDE 'admin/header.html' title=tprintf(loc('Response Priorities for %s'), body.name) -%]
-
-<table>
- <thead>
- <tr>
- <th> [% loc('Name') %] </th>
- <th> [% loc('Description') %] </th>
- <th> [% loc('Categories') %] </th>
- <th> [% loc('Default') %] </th>
- <th> &nbsp; </th>
- </tr>
- </thead>
- <tbody>
- [% FOR p IN response_priorities %]
- <tr [% 'class="is-deleted"' IF p.deleted %]>
- <td> [% p.name | html %] </td>
- <td> [% p.description | html %] </td>
- <td>
- [% UNLESS p.contacts.size %]
- <em>[% loc('All categories') %]</em>
- [% ELSE %]
- [% FOR contact IN p.contacts %]
- [% contact.category_display %][% ',' UNLESS loop.last %]
- [% END %]
- [% END %]
- </td>
- <td> [% IF p.is_default %]X[% END %]</td>
- <td> <a href="[% c.uri_for('', body.id, p.id) %]" class="btn">[% loc('Edit') %]</a> </td>
- </tr>
- [% END %]
- </tbody>
-</table>
-
-<a href="[% c.uri_for('', body.id, 'new') %]" class="btn">[% loc('New priority') %]</a>
-
-[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/roles/form.html b/templates/web/base/admin/roles/form.html
new file mode 100644
index 000000000..1801746af
--- /dev/null
+++ b/templates/web/base/admin/roles/form.html
@@ -0,0 +1,32 @@
+[% INCLUDE 'admin/header.html' title=loc('Roles') -%]
+
+<form method="post">
+ <div class="admin-hint">
+ <p>[% loc("The role's <strong>name</strong> is used to refer to this group of permissions elsewhere in the admin.") %]</p>
+ </div>
+ [% form.field('name').render | safe %]
+
+ [% IF form.field('body').is_active %]
+ [% form.field('body').render | safe %]
+ [% END %]
+
+ <div class="admin-hint">
+ <p>[% loc("Users with this role can perform the following actions within their assigned body or area.") %]</p>
+ </div>
+ [% form.field('permissions').render | safe %]
+
+ [% form.field('submit').render | safe %]
+
+ <p>
+ <input class="btn" type="submit" name="submit" value="[% loc('Save changes') %]">
+ </p>
+ [% IF form.item.id %]
+ <p>
+ <input class="btn-danger" type="submit" name="delete_role" value="[% loc('Delete') %]" data-confirm="[% loc('Are you sure?') %]">
+ </p>
+ [% END %]
+</form>
+
+<p><a href="[% c.uri_for(c.controller.action_for('list')) %]">Return to roles list</a></p>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/roles/index.html b/templates/web/base/admin/roles/index.html
new file mode 100644
index 000000000..6c561199c
--- /dev/null
+++ b/templates/web/base/admin/roles/index.html
@@ -0,0 +1,35 @@
+[% INCLUDE 'admin/header.html' title=loc('Roles') -%]
+
+<table>
+ <tr>
+ <th>[% loc('Role') %]</th>
+ <th>[% loc('Permissions') %]</th>
+ <th>&nbsp;</th>
+ </tr>
+[% FOREACH role IN roles -%]
+ [% IF c.user.is_superuser AND last_name != role.body.name %]
+ <tr>
+ <td colspan="3"><strong>[% role.body.name %]</strong></td>
+ </tr>
+ [% SET last_name = role.body.name %]
+ [% END %]
+ <tr>
+ <td>[% role.name | html %]</td>
+ <td><ul class="no-margin no-bullets">
+ [% FOR perm IN role.permissions.sort %]
+ <li>[% labels.$perm %]
+ [% END %]
+ </ul></td>
+ <td>
+ <a href="[% c.uri_for(c.controller.action_for('edit'), [role.id]) %]">[% loc('Edit') %]</a>
+ &middot; <a href="[% c.uri_for_action('admin/users/index', role = role.id) %]">[% loc('Users') %]</a>
+ </td>
+ </tr>
+[% END -%]
+</table>
+
+<p>
+ <a href="[% c.uri_for(c.controller.action_for('create')) %]">[% loc('Create') %]</a>
+</p>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/states/index.html b/templates/web/base/admin/states/index.html
index 1b68d4aea..ca2ef03d2 100644
--- a/templates/web/base/admin/states/index.html
+++ b/templates/web/base/admin/states/index.html
@@ -45,7 +45,7 @@
</td>
<td style="text-align:center;vertical-align:middle" rowspan="[% rows %]">
[% IF state.label != 'confirmed' AND state.label != 'closed' %]
- <input class="btn btn--small" type="submit" name="delete:[% state.label %]" value="Delete">
+ <input class="btn btn--small btn-danger" type="submit" data-confirm="[% loc('Are you sure?') %]" name="delete:[% state.label %]" value="Delete">
[% END %]
</td>
</tr>
diff --git a/templates/web/base/admin/stats/index.html b/templates/web/base/admin/stats/index.html
index d47054427..e6ba5e054 100644
--- a/templates/web/base/admin/stats/index.html
+++ b/templates/web/base/admin/stats/index.html
@@ -1,10 +1,27 @@
[% INCLUDE 'admin/header.html' title=loc('Stats') %]
+[% INCLUDE 'status/stats.html' admin_include_users=1 %]
+
+[% IF c.cobrand.admin_show_creation_graph -%]
+ <p>
+ <a href="[% c.config.BASE_URL %]/fms-live-creation.png" class="admin-offsite-link">[% loc('Graph of problem creation by status over time') %]</a>
+ </p>
+[% END -%]
+
<ul>
<li><a href="[% c.uri_for_action('admin/stats/questionnaire') %]">[% loc('Survey Results') %]</a></li>
<li><a href="[% c.uri_for_action('admin/stats/state') %]">[% loc('Problem breakdown by state') %]</a></li>
<li><a href="[% c.uri_for_action('admin/stats/fix_rate') %]">[% loc('Category fix rate for problems > 4 weeks old') %]</a></li>
<li><a href="[% c.uri_for_action('dashboard/index') %]">[% loc('Summary statistics') %]</a></li>
+[% IF c.cobrand.feature('heatmap').keys %]
+ <li>[% loc('Heatmap') %] <ul>
+ [% FOR body IN c.cobrand.feature('heatmap').pairs %]
+ <li><a href="[% c.uri_for_action('dashboard/heatmap') %]?body=[% body.value %]">[% body.key %]</a></li>
+ [% END %]
+ </ul> </li>
+[% ELSIF c.cobrand.feature('heatmap') %]
+<li><a href="[% c.uri_for_action('dashboard/heatmap') %]">[% loc('Heatmap') %]</a></li>
+[% END %]
[% IF c.cobrand.moniker == 'fixmystreet' %]
<li><a href="[% c.uri_for_action('admin/stats/refused') %]">Refused</a></li>
[% END %]
diff --git a/templates/web/base/admin/template_edit.html b/templates/web/base/admin/templates/edit.html
index 2945e36c5..7ce67f96f 100644
--- a/templates/web/base/admin/template_edit.html
+++ b/templates/web/base/admin/templates/edit.html
@@ -4,7 +4,7 @@
[% UNLESS rt.id %]<h3>[% loc('New template') %]</h3>[% END %]
<form method="post"
- action="[% c.uri_for('templates', body.id, rt.id || 'new' ) %]"
+ action="[% c.uri_for_action('/admin/templates/edit', body.id, rt.id || 'new' ) %]"
enctype="application/x-www-form-urlencoded"
accept-charset="utf-8"
class="validate">
@@ -13,7 +13,9 @@
<p class="error">[% loc('Please correct the errors below') %]</p>
[% END %]
-
+ [% IF errors.title %]
+ <div class="form-error">[% errors.title %]</div>
+ [% END %]
<div class="admin-hint">
<p>
[% loc('This is a <strong>private</strong> name for this template so you can identify it when updating reports or editing in the admin.') %]
diff --git a/templates/web/base/admin/templates_index.html b/templates/web/base/admin/templates/index.html
index 40e1be300..9322c6ef6 100644
--- a/templates/web/base/admin/templates_index.html
+++ b/templates/web/base/admin/templates/index.html
@@ -3,7 +3,7 @@
<ul>
[% FOR body IN bodies %]
<li>
- <a href="[% c.uri_for('templates', body.id) %]">[% body.name %]</a>
+ <a href="[% c.uri_for_action('/admin/templates/view', body.id) %]">[% body.name %]</a>
</li>
[% END %]
</ul>
diff --git a/templates/web/base/admin/templates.html b/templates/web/base/admin/templates/view.html
index 21e4eea25..6a1dd9614 100644
--- a/templates/web/base/admin/templates.html
+++ b/templates/web/base/admin/templates/view.html
@@ -28,12 +28,12 @@
[% IF t.external_status_code %][% t.external_status_code | html %] (external)[% END %]
</td>
<td> [% IF t.auto_response %]X[% END %] </td>
- <td> <a href="[% c.uri_for('templates', body.id, t.id) %]" class="btn">[% loc('Edit') %]</a> </td>
+ <td> <a href="[% c.uri_for_action('/admin/templates/edit', body.id, t.id) %]" class="btn">[% loc('Edit') %]</a> </td>
</tr>
[% END %]
</tbody>
</table>
-<a href="[% c.uri_for('templates', body.id, 'new') %]" class="btn">[% loc('New template') %]</a>
+<a href="[% c.uri_for_action('/admin/templates/index', body.id, 'new') %]" class="btn">[% loc('New template') %]</a>
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/triage/_inspect.html b/templates/web/base/admin/triage/_inspect.html
new file mode 100644
index 000000000..926197ceb
--- /dev/null
+++ b/templates/web/base/admin/triage/_inspect.html
@@ -0,0 +1,77 @@
+[% BLOCK category_list %]
+<select class="form-control" name="[% field_name %]" id="[% field_name %]">
+ [% IF category_options.size %]
+ [%~ IF category_groups.size ~%]
+ [%~ FOREACH group IN category_groups ~%]
+ [% IF group.name %]<optgroup label="[% group.name %]">[% END %]
+ [% group_select = 0 %]
+ [% selected = 0 %]
+ [%~ FOREACH cat_op IN group.categories ~%]
+ [% IF group_select == 0 AND problem.category == group.name %]
+ [% selected = 1; group_select = 1 %]
+ [% END %]
+ <option value="[% cat_op.category | html %]"[% ' selected' IF selected OR problem.category == cat_op.category %]>[% cat_op.category_display | html %] ([% cat_op.email | html %])</option>
+ [% selected = 0 %]
+ [%~ END ~%]
+ [% IF group.name %]</optgroup>[% END %]
+ [%~ END =%]
+ [% ELSE %]
+ [% FOREACH cat IN category_options %]
+ <option value="[% cat.category | html %]"[% ' selected' IF problem.category == cat.category %]>[% cat.category_display | html %]</option>
+ [% END %]
+ [% END %]
+ [% END %]
+</select>
+[% END %]
+
+[% permissions = c.user.permissions(problem) %]
+[% second_column = BLOCK -%]
+ <div id="side-inspect">
+
+ <h2 class="inspect-form-heading">[% loc('Inspect report') %]</h2>
+
+ [% INCLUDE 'errors.html' %]
+
+ <form name="report_inspect_form" id="report_inspect_form" method="post" action="[% c.uri_for( '/report', problem.id ) %]" class="validate">
+
+ [% INCLUDE 'report/inspect/information.html' no_relocate=1 %]
+
+ [% IF permissions.report_edit_category OR permissions.report_inspect OR permissions.triage %]
+ <div class="inspect-section">
+ <p>
+ <strong>Holding category:</strong> [% problem.category %]
+ </p>
+
+ <p>
+ <label for="category">CONFIRM Subject</label>
+ [% PROCESS category_list category_groups=end_groups field_name="category" categories_hash=end_categories category_options=end_options %]
+ </p>
+
+ </div>
+ [% END %]
+
+ <div class="inspect-section">
+ [%- extra_fields = problem.get_extra_fields -%]
+ [% FOR field IN extra_fields %]
+ [% NEXT IF field.name == 'urgent' %]
+ <p>
+ <label for="[% field.name %]">[% field.description %]</label>
+ <input class="form-control" name="[% field.name %]" type="text" value="[% field.value | html %]" disabled>
+ </p>
+ [% END %]
+
+ [% IF permissions.report_inspect OR permissions.triage %]
+ [% INCLUDE 'report/inspect/public_update.html' public_update_defaulted=0 %]
+ [% END %]
+
+ <p>
+ <input type="hidden" name="token" value="[% csrf_token %]" />
+ <input class="btn btn-primary" type="submit" value="[% loc('Save changes') %]" data-value-original="[% loc('Save changes') %]" data-value-duplicate="[% loc('Save + close as duplicate') %]" name="save" />
+ </p>
+ </div>
+
+ <input type="hidden" name="js" value="">
+ <input type="hidden" name="triage" value="1">
+ </form>
+ </div>
+[%- END %]
diff --git a/templates/web/base/admin/triage/_list-filters.html b/templates/web/base/admin/triage/_list-filters.html
new file mode 100644
index 000000000..dd3e17875
--- /dev/null
+++ b/templates/web/base/admin/triage/_list-filters.html
@@ -0,0 +1,53 @@
+[% select_category = BLOCK %]
+ [% IF filter_categories.size %]
+ <select class="form-control js-multiple" name="filter_category" id="filter_categories" multiple data-all="[% loc('Everything') %]">
+ [% FOR cat IN filter_categories %]
+ <option value="[% cat.category | html %]"[% ' selected' IF filter_category.${cat.category} %]>
+ [% cat.category_display | html %]
+ [%~ IF cat.get_extra_metadata('help_text') %] ([% cat.get_extra_metadata('help_text') %])[% END ~%]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ [% loc('Everything') %]
+ [% END %]
+[% END %]
+
+<div class="report-list-filters-wrapper">
+
+[% IF use_form_wrapper %]
+ <form method="get" action="">
+[% END %]
+
+ <p class="report-list-filters">
+ [% tprintf(loc('<label for="statuses">Show</label> %s reports <label for="filter_categories">about</label> %s', "The first %s is a dropdown of all/fixed/etc, the second is a dropdown of categories"), 'untriaged', mark_safe(select_category)) %]
+ <input type="submit" name="filter_update" value="[% loc('Go') %]">
+ </p>
+
+ <p class="report-list-filters">
+ <label for="sort">[% loc('Sort by') %]</label>
+ <select class="form-control" name="sort" id="sort">
+ [% IF shortlist %]
+ <option value="shortlist"[% ' selected' IF sort_key == 'shortlist' %]>[% loc('Manual order') %]</option>
+ [% END %]
+ <option value="created-desc"[% ' selected' IF sort_key == 'created-desc' %]>[% loc('Newest') %]</option>
+ <option value="created-asc"[% ' selected' IF sort_key == 'created-asc' %]>[% loc('Oldest') %]</option>
+ <option value="updated-desc"[% ' selected' IF sort_key == 'updated-desc' %]>[% loc('Recently updated') %]</option>
+ <option value="updated-asc"[% ' selected' IF sort_key == 'updated-asc' %]>[% loc('Least recently updated') %]</option>
+ <option value="comments-desc"[% ' selected' IF sort_key == 'comments-desc' %]>[% loc('Most commented') %]</option>
+ </select>
+ <input type="submit" name="filter_update" value="[% loc('Go') %]">
+ </p>
+ [% IF page == 'around' %]
+ <p id="show_old_reports_wrapper" class="report-list-filters[% ' hidden' UNLESS num_old_reports > 0 %]">
+ <label for="show_old_reports">[% loc('Show older reports') %]</label>
+ <input type="checkbox" name="show_old_reports" id="show_old_reports" value="1"[% ' checked' IF show_old_reports %]>
+ <input type="submit" name="filter_update" value="[% loc('Go') %]">
+ </p>
+ [% END %]
+
+[% IF use_form_wrapper %]
+ </form>
+[% END %]
+
+</div>
diff --git a/templates/web/base/admin/triage/index.html b/templates/web/base/admin/triage/index.html
new file mode 100644
index 000000000..8b6880c24
--- /dev/null
+++ b/templates/web/base/admin/triage/index.html
@@ -0,0 +1,42 @@
+[% SET body_name = body.name %]
+[% IF c.cobrand.moniker == 'hounslow' %]
+ [% SET body_name = 'Hounslow Highways' %]
+[% ELSIF c.cobrand.moniker == 'isleofwight' %]
+ [% SET body_name = 'Island Roads' %]
+[% END %]
+
+[%
+ PROCESS "report/photo-js.html";
+ PROCESS "maps/${map.type}.html";
+ SET bodyclass = 'mappage';
+ INCLUDE 'header.html',
+ title = 'Awaiting triage'
+ rss = [ tprintf(loc('Problems within %s, %s', "First %s is the body name, second %s the site name"), name, site_name), rss_url ]
+%]
+
+[% map_html | safe %]
+
+</div>
+<div id="map_sidebar">
+ <div id="side">
+
+ <h1 id="reports_heading">
+ Awaiting triage
+ </h1>
+
+<section class="full-width">
+[% INCLUDE "admin/triage/_list-filters.html", use_form_wrapper = 1 %]
+<div class="js-pagination">
+[% INCLUDE 'pagination.html', param = 'p' %]
+</div>
+<div id="js-reports-list">
+ [% INCLUDE 'reports/_problem-list.html' %]
+</div>
+<div class="js-pagination">
+[% INCLUDE 'pagination.html', param = 'p' %]
+</div>
+</section>
+
+ </div>
+</div>
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/admin/update_edit.html b/templates/web/base/admin/update_edit.html
index fca9b1904..527b3f9f8 100644
--- a/templates/web/base/admin/update_edit.html
+++ b/templates/web/base/admin/update_edit.html
@@ -1,7 +1,7 @@
[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing update %d'), update.id ) -%]
[% PROCESS 'admin/report_blocks.html' %]
-[% status_message %]
+[% INCLUDE status_message %]
<form method="post" action="[% c.uri_for( 'update_edit', update.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
<input type="hidden" name="token" value="[% csrf_token %]" >
diff --git a/templates/web/base/admin/users/edit.html b/templates/web/base/admin/users/edit.html
index 8dd2b926f..204e58607 100644
--- a/templates/web/base/admin/users/edit.html
+++ b/templates/web/base/admin/users/edit.html
@@ -6,7 +6,7 @@
[% INCLUDE 'admin/header.html' title=title -%]
[% PROCESS 'admin/report_blocks.html' %]
-[% status_message %]
+[% INCLUDE status_message %]
[% INCLUDE 'admin/users/form.html' %]
diff --git a/templates/web/base/admin/users/form.html b/templates/web/base/admin/users/form.html
index 8f0f9ad6e..495da8648 100644
--- a/templates/web/base/admin/users/form.html
+++ b/templates/web/base/admin/users/form.html
@@ -1,4 +1,7 @@
-<form method="post" id="user_edit" action="[% c.uri_for_action( 'admin/users/edit', user.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+<form method="post" id="user_edit" action="[%
+ SET action_end = user.id || 'add';
+ c.uri_for_action( 'admin/users/edit', [ action_end ] )
+ %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
<input type="hidden" name="token" value="[% csrf_token %]" >
<input type="hidden" name="submit" value="1" >
@@ -116,29 +119,6 @@
</label>
</li>
- [% UNLESS user.is_superuser %]
- <li>
- <div class="admin-hint">
- <p>
- [% loc("Reports made by trusted users will be sent to the responsible body without being inspected first.") %]
- </p>
- </div>
- [% IF c.user.is_superuser %]
- <label for="trusted_bodies">[% loc('Trusted by bodies:') %]</label>
- <select class="form-control js-multiple" id='trusted_bodies' name='trusted_bodies' multiple>
- [% FOR body IN bodies %]
- <option value="[% body.id %]"[% ' selected' IF user.has_permission_to('trusted', body.id) %]>[% body.name %]</option>
- [% END %]
- </select>
- [% ELSE %]
- <label>
- [% loc('Trusted:') %]
- <input type="checkbox" id="trusted_bodies" name="trusted_bodies" value="[% c.user.from_body.id %]" [% 'checked' IF user.has_permission_to('trusted', c.user.from_body.id) %]>
- </label>
- [% END %]
- </li>
- [% END %]
-
[% IF c.user.is_superuser %]
<li>
<div class="admin-hint">
@@ -155,6 +135,20 @@
[% IF available_permissions AND NOT user.is_superuser %]
<li>
+ <div class="admin-hint">
+ <p>
+ [% loc("Users can be assigned one or more roles to give them all the permissions of those roles. Selecting a role or roles will disable manual permission selection.") %]
+ </p>
+ </div>
+ <label for="roles">[% loc('Role:') %]</label>
+ <select class="form-control js-multiple" id="roles" name="roles" multiple>
+ [% FOREACH role IN roles %]
+ <option data-permissions='["[% role.permissions.join('","') | html %]"]' value="[% role.id %]"[% ' selected' IF user.in_role(role.id) %]>[% role.name | html %]</option>
+ [% END %]
+ </select>
+ </li>
+
+ <li>
<fieldset>
<legend>
<div class="admin-hint">
diff --git a/templates/web/base/admin/users/import.html b/templates/web/base/admin/users/import.html
index 0c0b903d7..38e4fe240 100644
--- a/templates/web/base/admin/users/import.html
+++ b/templates/web/base/admin/users/import.html
@@ -1,7 +1,7 @@
[% INCLUDE 'admin/header.html' title=loc("User Import") -%]
[% PROCESS 'admin/report_blocks.html' %]
-[% status_message %]
+[% INCLUDE status_message %]
<form method="post" id="user_edit" enctype="multipart/form-data" accept-charset="utf-8">
<input type="hidden" name="token" value="[% csrf_token %]" >
@@ -27,7 +27,7 @@
[% FOREACH user IN new_users %]
<tr>
<td>
- <a href="[% c.uri_for_action( 'admin/users/edit', user.id ) %]">
+ <a href="[% c.uri_for_action( 'admin/users/edit', [ user.id ] ) %]">
[% user.name %]
</a>
</td>
@@ -50,7 +50,7 @@
[% FOREACH user IN existing_users %]
<tr>
<td>
- <a href="[% c.uri_for_action( 'admin/users/edit', user.id ) %]">
+ <a href="[% c.uri_for_action( 'admin/users/edit', [ user.id ] ) %]">
[% user.name %]
</a>
</td>
@@ -65,11 +65,12 @@
<p>[% loc('This page is a quick way to create many new staff users in one go.') %]</p>
<p>[% loc("Existing users won't be modified.") %]</p>
<p>
- [% loc("The uploaded CSV file must contain a header row, and records must have the following fields (in this order):") %]
- <pre>name,email,from_body,permissions</pre>
+ [% loc("The uploaded CSV file must contain a header row, and records can have the following fields:") %]
+ <pre>name,email,from_body,permissions,roles,passwordhash</pre>
<ul>
<li><code>from_body</code>: [% loc("the database id of the body to associate that user with, e.g. <code>2217</code> for Buckinghamshire.") %]</li>
<li><code>permissions</code>: [% loc("a colon-separated list of permissions to grant that user, e.g. <code>contribute_as_body:moderate:user_edit</code>.") %]</li>
+ <li><code>roles</code>: [% loc("a colon-separated list of roles to assign to that user.") %]</li>
</ul>
</p>
diff --git a/templates/web/base/admin/users/index.html b/templates/web/base/admin/users/index.html
index e939f008b..e573c10fe 100644
--- a/templates/web/base/admin/users/index.html
+++ b/templates/web/base/admin/users/index.html
@@ -1,42 +1,89 @@
[% INCLUDE 'admin/header.html' title=loc('Search Users') %]
[% PROCESS 'admin/report_blocks.html' %]
+[% BLOCK role_select %]
+<select name="[% label %]" id="[% label %]" class="form-control">
+ <option value="">---</option>
+ [% FOR role IN roles %]
+ [% IF c.user.is_superuser AND last_name != role.body.name %]
+ <optgroup label="[% role.body.name %]">
+ [% SET last_name = role.body.name %]
+ [% END %]
+ <option value="[% role.id %]"[% ' selected' IF role.id == role_selected %]>[% role.name | html %]</option>
+ [% END %]
+</select>
+[% END %]
+
+[% INCLUDE status_message %]
+
<div class="fms-admin-info">
[% loc("User search finds matches in users' names and email addresses.") %]
</div>
+
<form method="get" action="[% c.uri_for_action('admin/users/index') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+<div class="filters">
+
<p><label for="search">[% loc('Search:') %]</label>
<input class="form-control" type="text" name="search" size="30" id="search" value="[% searched | html %]">
+ [% IF roles %]
+ <p><label for="role">[% loc('Role:') %]</label>
+ [% INCLUDE role_select label='role' %]
+ [% END %]
+ <p class="no-label"><input type="submit" value="[% loc('Go') %]" class="btn">
+
+</div>
</form>
[% IF users.size %]
+<form method="post">
<table cellspacing="0" cellpadding="2" border="1">
<tr>
+ <th>*</th>
<th>[% loc('Name') %]</th>
<th>[% loc('Email') %]</th>
<th>[% loc('Body') %]</th>
[% IF c.cobrand.moniker != 'zurich' %]
<th>[% loc('Flagged') %]</th>
[% END %]
- <th>*</th>
+ <th colspan="2">*</th>
</tr>
[%- FOREACH user IN users %]
<tr>
- <td>[% PROCESS value_or_nbsp value=user.name %]</td>
- <td><a href="[% c.uri_for_action( 'admin/reports', search => user.email ) %]">[% PROCESS value_or_nbsp value=user.email %]</a></td>
+ <td align="center">[% IF user.from_body %]
+ <input type="checkbox" name="uid" value="[% user.id %]" id="uid[% user.id %]">
+ [% END %]</td>
+ <td>[% IF user.from_body %]<label class="inline" for="uid[% user.id %]">[% END %]
+ [% PROCESS value_or_nbsp value=user.name %]
+ [% IF user.from_body %]</label>[% END %]
+ </td>
+ <td><a href="[% c.uri_for_action( 'admin/reports/index', search => user.email ) %]">[% PROCESS value_or_nbsp value=user.email %]</a></td>
<td>[% PROCESS value_or_nbsp value=user.from_body.name %]
[% IF user.is_superuser %] * [% END %]
</td>
[% IF c.cobrand.moniker != 'zurich' %]
<td>[% user.flagged == 2 ? loc('User in abuse table') : user.flagged ? loc('Yes') : '&nbsp;' %]</td>
[% END %]
- <td>[% IF user.id %]<a href="[% c.uri_for_action( 'admin/users/edit', user.id ) %]">[% loc('Edit') %]</a>[% END %]</td>
+ <td>[% IF user.id %]<a href="[% c.uri_for_action( 'admin/users/edit', [ user.id ] ) %]">[% loc('Edit') %]</a>[% END %]</td>
+ <td>[% IF user.id %]<a href="[% c.uri_for_action( 'admin/users/log', [ user.id ] ) %]">[% loc('Timeline') %]</a>[% END %]</td>
</tr>
[%- END -%]
</table>
-[% ELSIF searched %]
+<p><label for="roles">[% loc('Assign selected to role:') %]</label>
+[% IF c.user.is_superuser %]
+[% INCLUDE role_select label='roles' %]
+[% ELSE %]
+<select class="form-control js-multiple" id="roles" name="roles" multiple>
+ [% FOREACH role IN roles %]
+ <option value="[% role.id %]">[% role.name | html %]</option>
+ [% END %]
+</select>
+[% END %]
+<p><input class="btn" type="submit" value="[% loc('Save changes') %]">
+</form>
+
+[% ELSIF searched || role_selected %]
<div class="fms-admin-warning">
[% loc("Searching found no users.") %]
@@ -44,7 +91,7 @@
[% END %]
-[% IF NOT searched %]
+[% IF NOT ( searched || role_selected )%]
<h2>[% loc('Add user') %]</h2>
[% INCLUDE 'admin/users/form.html', user = '' %]
[% ELSE %]
diff --git a/templates/web/base/admin/users/log.html b/templates/web/base/admin/users/log.html
new file mode 100644
index 000000000..4b426e0ba
--- /dev/null
+++ b/templates/web/base/admin/users/log.html
@@ -0,0 +1,72 @@
+[% INCLUDE 'admin/header.html' title=loc('Timeline') _ ', ' _ user.name %]
+
+<style>
+.timeline ul {
+ margin-bottom: 0;
+}
+.timeline dd {
+ margin-bottom: 0;
+}
+</style>
+
+[%
+action_map = {
+ add = 'Added'
+ delete = 'Deleted'
+ edit = 'Edited'
+ merge = 'Merged'
+ moderation = 'Moderated'
+ resend = 'Resent'
+ category_change = 'Changed category of'
+ state_change = 'Changed state of'
+}
+%]
+
+[%- date = '' %]
+[% FOREACH moment IN time.keys.sort.reverse %]
+ [%- curdate = time.$moment.0.date.strftime('%A, %e %B %Y') -%]
+ [%- IF date != curdate %]
+ [% '</dl>' IF date %]
+ <h2>[% curdate %]</h2>
+
+ <dl class="timeline">
+ [%- date = curdate -%]
+ [%- END -%]
+ <dt><b>[% time.$moment.0.date.hms %]</b></dt>
+ <dd><ul>
+ [% FOREACH item IN time.$moment %]
+ <li>
+ [%~ IF item.obj.problem_id %]
+ [%~ SET report_url = c.uri_for( '/report', item.obj.problem_id ) _ "#update_" _ item.obj.id %]
+ [%~ ELSE %]
+ [%~ SET report_url = c.uri_for('/report', item.obj.id) %]
+ [%~ END %]
+ [%~ SET report_link = "<a href='" _ report_url _ "'>" _ item.obj.id _ "</a>" %]
+ [%- SWITCH item.type -%]
+ [%~ CASE 'problem' %]
+ [%- tprintf(loc('Problem %s created'), mark_safe(report_link)) %], ‘[% item.obj.title | html %]’
+ [%~ CASE 'problemContributedBy' %]
+ [%- tprintf(loc('Problem %s created on behalf of %s'), mark_safe(report_link), item.obj.name) %], ‘[% item.obj.title | html %]’
+ [%~ CASE 'update' %]
+ [% tprintf(loc("Update %s created for problem %d"), mark_safe(report_link), item.obj.problem_id) %]
+ [% item.obj.text | add_links | markup(item.obj.user) | html_para %]
+ [%~ CASE 'shortlistAdded' %]
+ [%- tprintf(loc('Problem %s added to shortlist'), mark_safe(report_link)) %]
+ [%~ CASE 'shortlistRemoved' %]
+ [%- tprintf(loc('Problem %s removed from shortlist'), mark_safe(report_link)) %]
+ [%~ CASE 'log' %]
+ [%~ SET object_summary = item.log.object_summary %]
+ [% IF object_summary %]
+ [%~ SET link = tprintf('<a href="%s">%s</a>', item.log.link, object_summary) %]
+ [%- tprintf('%s %s %s', action_map.${item.log.action}, item.log.actual_object_type, mark_safe(link)) %]
+ [% ' – ' _ item.log.reason IF item.log.reason %]
+ [% ELSE %]
+ [%- tprintf('%s %s %s', action_map.${item.log.action}, item.log.actual_object_type, item.log.object_id) %]
+ [% END %]
+ [%- END %]
+ </li>
+ [%- END %]
+ </ul></dd>
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]