mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-05-31 11:30:28 -04:00
Display the template folders nested on the move template/folder form
Before, all the folders were displayed in a list which was ordered but not nested. This changes the move form to nest the template folders.
This commit is contained in:
@@ -742,6 +742,26 @@ class RadioFieldWithNoneOption(FieldWithNoneOption, RadioField):
|
||||
pass
|
||||
|
||||
|
||||
class NestedRadioField(RadioFieldWithNoneOption):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def children(self):
|
||||
child_map = {}
|
||||
child_ids = [
|
||||
folder['id'] for folder in self.all_template_folders
|
||||
if folder['parent_id'] is None]
|
||||
|
||||
child_map[None] = [option for idx, option in enumerate(self) if option.data in child_ids or idx == 0]
|
||||
|
||||
for option in self:
|
||||
child_ids = [
|
||||
folder['id'] for folder in self.all_template_folders
|
||||
if folder['parent_id'] == option.data]
|
||||
child_map[option.data] = [option for option in self if option.data in child_ids]
|
||||
return child_map
|
||||
|
||||
|
||||
class HiddenFieldWithNoneOption(FieldWithNoneOption, HiddenField):
|
||||
pass
|
||||
|
||||
@@ -1207,7 +1227,6 @@ class TemplateAndFoldersSelectionForm(Form):
|
||||
self,
|
||||
all_template_folders,
|
||||
template_list,
|
||||
current_folder_id,
|
||||
allow_adding_letter_template,
|
||||
allow_adding_copy_of_template,
|
||||
*args,
|
||||
@@ -1221,13 +1240,10 @@ class TemplateAndFoldersSelectionForm(Form):
|
||||
self.op = None
|
||||
self.is_move_op = self.is_add_folder_op = self.is_add_template_op = False
|
||||
|
||||
if current_folder_id is None:
|
||||
current_folder_id = RadioFieldWithNoneOption.NONE_OPTION_VALUE
|
||||
|
||||
self.move_to.all_template_folders = all_template_folders
|
||||
self.move_to.choices = [
|
||||
(item['id'], item['name'])
|
||||
for item in ([self.ALL_TEMPLATES_FOLDER] + all_template_folders)
|
||||
if item['id'] != current_folder_id
|
||||
]
|
||||
|
||||
self.add_template_by_template_type.choices = list(filter(None, [
|
||||
@@ -1262,10 +1278,12 @@ class TemplateAndFoldersSelectionForm(Form):
|
||||
templates_and_folders = MultiCheckboxField('Choose templates or folders', validators=[
|
||||
required_for_ops('move-to-new-folder', 'move-to-existing-folder')
|
||||
])
|
||||
move_to = RadioFieldWithNoneOption('Choose a folder', validators=[
|
||||
Optional(),
|
||||
required_for_ops('move-to-new-folder', 'move-to-existing-folder')
|
||||
])
|
||||
move_to = NestedRadioField(
|
||||
'Choose a folder',
|
||||
validators=[
|
||||
Optional(),
|
||||
required_for_ops('move-to-new-folder', 'move-to-existing-folder')
|
||||
])
|
||||
add_new_folder_name = StringField('Folder name', validators=[required_for_ops('add-new-folder')])
|
||||
move_to_new_folder_name = StringField('Folder name', validators=[required_for_ops('move-to-new-folder')])
|
||||
|
||||
|
||||
@@ -116,13 +116,13 @@ def choose_template(service_id, template_type='all', template_folder_id=None):
|
||||
all_template_folders=current_service.all_template_folders,
|
||||
template_list=template_list,
|
||||
template_type=template_type,
|
||||
current_folder_id=template_folder_id,
|
||||
allow_adding_letter_template=current_service.has_permission('letter'),
|
||||
allow_adding_copy_of_template=(
|
||||
current_service.all_templates or
|
||||
len(user_api_client.get_service_ids_for_user(current_user)) > 1
|
||||
),
|
||||
)
|
||||
|
||||
if request.method == 'POST' and templates_and_folders_form.validate_on_submit():
|
||||
if not can_manage_folders():
|
||||
abort(403)
|
||||
@@ -149,6 +149,7 @@ def choose_template(service_id, template_type='all', template_folder_id=None):
|
||||
template_type=template_type,
|
||||
search_form=SearchTemplatesForm(),
|
||||
templates_and_folders_form=templates_and_folders_form,
|
||||
move_to_children=templates_and_folders_form.move_to.children()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,43 @@
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radio_list(
|
||||
options,
|
||||
child_map,
|
||||
disable=[],
|
||||
option_hints={}
|
||||
) %}
|
||||
<ul>
|
||||
{% for option in options %}
|
||||
{% if child_map[option.data] %}
|
||||
{% call radio(option, disable, option_hints, as_list_item=True) %}
|
||||
{{ radio_list(child_map[option.data], child_map, disable, option_hints) }}
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{{ radio(option, disable, option_hints, as_list_item=True) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radios_nested(
|
||||
field,
|
||||
child_map,
|
||||
hint=None,
|
||||
disable=[],
|
||||
option_hints={},
|
||||
hide_legend=False
|
||||
) %}
|
||||
{% set disable = [current_option_id] %}
|
||||
{% call radios_wrapper(
|
||||
field, hint, disable, option_hints, hide_legend
|
||||
) %}
|
||||
{{ radio_list(child_map[None], child_map, disable) }}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro radios_wrapper(field, hint=None, disable=[], option_hints={}, hide_legend=False) %}
|
||||
<div class="form-group {% if field.errors %} form-group-error{% endif %}">
|
||||
<fieldset>
|
||||
@@ -37,8 +74,12 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro radio(option, disable=[], option_hints={}, data_target=None) %}
|
||||
{% macro radio(option, disable=[], option_hints={}, data_target=None, as_list_item=False) %}
|
||||
{% if as_list_item %}
|
||||
<li class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% else %}
|
||||
<div class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% endif %}
|
||||
<input
|
||||
id="{{ option.id }}" name="{{ option.name }}" type="radio" value="{{ option.data }}"
|
||||
{% if option.data in disable %}
|
||||
@@ -56,7 +97,14 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</label>
|
||||
{% if caller %}
|
||||
{{ caller() }}
|
||||
{% endif %}
|
||||
{% if as_list_item %}
|
||||
</li>
|
||||
{% else %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% from "components/radios.html" import radios %}
|
||||
{% from "components/radios.html" import radios, radios_nested %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
|
||||
<div id="sticky_template_forms" class="js-stick-at-bottom-when-scrolling">
|
||||
@@ -6,7 +6,7 @@
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
{% if templates_and_folders_form.move_to.choices and template_list.templates_to_show %}
|
||||
<div id="move_to_folder_radios">
|
||||
{{ radios(templates_and_folders_form.move_to) }}
|
||||
{{ radios_nested(templates_and_folders_form.move_to, move_to_children, current_option) }}
|
||||
{{ page_footer('Move', button_name='operation', button_value='move-to-existing-folder') }}
|
||||
</div>
|
||||
<div id="move_to_new_folder_form">
|
||||
|
||||
@@ -13,6 +13,7 @@ from tests.conftest import (
|
||||
normalize_spaces,
|
||||
)
|
||||
|
||||
ROOT_FOLDER_ID = '__NONE__'
|
||||
PARENT_FOLDER_ID = '7e979e79-d970-43a5-ac69-b625a8d147b0'
|
||||
CHILD_FOLDER_ID = '92ee1ee0-e4ee-4dcc-b1a7-a5da9ebcfa2b'
|
||||
GRANDCHILD_FOLDER_ID = 'fafe723f-1d39-4a10-865f-e551e03d8886'
|
||||
@@ -791,10 +792,10 @@ def test_should_show_radios_and_buttons_for_move_destination_if_correct_permissi
|
||||
assert radios == page.select('input[name=move_to]')
|
||||
|
||||
assert [x['value'] for x in radios] == [
|
||||
PARENT_FOLDER_ID, CHILD_FOLDER_ID, FOLDER_ONE_TWO_ID, FOLDER_TWO_ID,
|
||||
ROOT_FOLDER_ID, PARENT_FOLDER_ID, CHILD_FOLDER_ID, FOLDER_ONE_TWO_ID, FOLDER_TWO_ID,
|
||||
]
|
||||
assert [x.text.strip() for x in radio_div.select('label')] == [
|
||||
'folder_one', 'folder_one_one', 'folder_one_two', 'folder_two',
|
||||
'All templates', 'folder_one', 'folder_one_one', 'folder_one_two', 'folder_two',
|
||||
]
|
||||
assert set(x['value'] for x in page.find_all('button', {'name': 'operation'})) == {
|
||||
'unknown',
|
||||
@@ -902,7 +903,7 @@ def test_should_be_able_to_move_a_sub_item(
|
||||
template_folder_id=PARENT_FOLDER_ID,
|
||||
_data={
|
||||
'operation': 'move-to-existing-folder',
|
||||
'move_to': '__NONE__',
|
||||
'move_to': ROOT_FOLDER_ID,
|
||||
'templates_and_folders': [GRANDCHILD_FOLDER_ID],
|
||||
},
|
||||
_expected_status=302,
|
||||
@@ -957,7 +958,7 @@ def test_should_be_able_to_move_a_sub_item(
|
||||
'operation': 'add-new-template',
|
||||
'templates_and_folders': [],
|
||||
'move_to_new_folder_name': '',
|
||||
'move_to': '__NONE__',
|
||||
'move_to': 'ROOT_FOLDER_ID',
|
||||
'add_template_by_template_type': 'email',
|
||||
},
|
||||
# add a new template, but don't select anything
|
||||
@@ -1005,6 +1006,7 @@ def test_no_action_if_user_fills_in_ambiguous_fields(
|
||||
]
|
||||
|
||||
assert [
|
||||
ROOT_FOLDER_ID,
|
||||
FOLDER_TWO_ID,
|
||||
PARENT_FOLDER_ID,
|
||||
] == [
|
||||
|
||||
Reference in New Issue
Block a user