backoffice: fold datasources in data management sidebar (#75959) #556

Merged
fpeters merged 1 commits from wip/75959-fold-datasources into main 2023-08-11 07:01:06 +02:00
3 changed files with 121 additions and 14 deletions

View File

@ -112,11 +112,11 @@ def test_backoffice_custom_view(pub):
resp = resp.follow()
assert resp.text.count('<span>User Label</span>') == 0
assert resp.text.count('<tr') == 3
assert resp.pyquery('#sidebar-custom-views li.active a').attr['href'] == '../user-custom-test-view/'
assert resp.pyquery('.sidebar-custom-views li.active a').attr['href'] == '../user-custom-test-view/'
resp = app.get('/backoffice/management/form-title/custom-test-view/')
assert resp.text.count('<tr') == 4
assert resp.pyquery('#sidebar-custom-views li.active a').attr['href'] == '../custom-test-view/'
assert resp.pyquery('.sidebar-custom-views li.active a').attr['href'] == '../custom-test-view/'
resp = app.get('/backoffice/management/form-title/user-custom-test-view/')
resp.forms['listing-settings']['filter-1-value'] = 'foo'
@ -1620,7 +1620,7 @@ def test_backoffice_hidden_data_source_custom_view(pub, user_perms):
app = login(get_app(pub))
resp = app.get('/backoffice/data/foo/')
visible_views = {x.attrib['href'] for x in resp.pyquery('#sidebar-custom-views a')}
visible_views = {x.attrib['href'] for x in resp.pyquery('.sidebar-custom-views a')}
if user_perms in ('admin', 'category_admin'):
assert visible_views == {'datasource-view/', 'custom-test-view/'}
@ -1697,3 +1697,49 @@ def test_backoffice_custom_view_group_by(pub):
'cde',
'def',
]
def test_backoffice_folded_data_sources(pub):
pub.user_class.wipe()
user = create_superuser(pub)
pub.custom_view_class.wipe()
CardDef.wipe()
carddef = CardDef()
carddef.name = 'foo'
carddef.fields = [
fields.StringField(id='1', label='Test', varname='foo'),
]
carddef.backoffice_submission_roles = user.roles
carddef.workflow_roles = {'_editor': user.roles[0]}
carddef.digest_templates = {
'default': 'plop',
'custom-view:custom-test-view': 'FOO {{ form_var_foo }}',
'custom-view:datasource-view': '{{ form_var_foo }}',
}
carddef.store()
custom_view = pub.custom_view_class()
custom_view.title = 'custom test view'
custom_view.formdef = carddef
custom_view.visibility = 'any'
custom_view.columns = {'list': [{'id': 'id'}]}
custom_view.filters = {}
custom_view.store()
custom_view = pub.custom_view_class()
custom_view.title = 'datasource view'
custom_view.formdef = carddef
custom_view.visibility = 'datasource'
custom_view.columns = {'list': [{'id': 'id'}]}
custom_view.filters = {}
custom_view.store()
app = login(get_app(pub))
resp = app.get('/backoffice/data/foo/')
assert resp.pyquery('.sidebar-custom-views').length == 2
assert resp.pyquery('fieldset.foldable.folded .sidebar-custom-views').length == 1
resp = resp.click('datasource view')
assert resp.pyquery('.sidebar-custom-views').length == 2
assert resp.pyquery('fieldset.foldable:not(.folded) .sidebar-custom-views').length == 1

View File

@ -904,21 +904,50 @@ class FormPage(FormdefDirectoryBase):
views = list(self.get_custom_views(criterias))
if views:
r += htmltext('<h3>%s</h3>') % _('Custom Views')
r += htmltext('<ul id="sidebar-custom-views">')
r += htmltext('<ul class="sidebar-custom-views">')
view_type = 'map' if self.view_type == 'map' else ''
datasource_views = []
for view in sorted(views, key=lambda x: getattr(x, 'title')):
if view.visibility == 'datasource':
datasource_views.append(view)
continue
if self._view:
active = bool(self._view.get_url_slug() == view.get_url_slug())
r += htmltext('<li class="active">' if active else '<li>')
r += htmltext('<a href="../%s/%s">%s</a>') % (view.get_url_slug(), view_type, view.title)
else:
r += htmltext('<li><a href="%s/%s">%s</a>') % (view.get_url_slug(), view_type, view.title)
if view.visibility == 'datasource':
r += htmltext(' <span class="as-data-source">(%s)</span>') % _('for data sources')
elif self.default_view and view.id == self.default_view.id:
if self.default_view and view.id == self.default_view.id:
r += htmltext(' <span class="default-custom-view">(%s)</span>') % _('default')
r += htmltext('</li>')
r += htmltext('</ul>')
if datasource_views:
klass = 'folded'
if self._view and any(
bool(self._view.get_url_slug() == x.get_url_slug()) for x in datasource_views
):
# current active view is a datasource, do not fold
klass = ''
r += htmltext(f'<fieldset class="sidebar-custom-datasource-views foldable {klass}">')
r += htmltext('<legend>%s</legend>') % _('Data sources')
r += htmltext('<ul class="sidebar-custom-views">')
for view in datasource_views:
if self._view:
active = bool(self._view.get_url_slug() == view.get_url_slug())
r += htmltext('<li class="active">' if active else '<li>')
r += htmltext('<a href="../%s/%s">%s</a>') % (
view.get_url_slug(),
view_type,
view.title,
)
else:
r += htmltext('<li><a href="%s/%s">%s</a>') % (
view.get_url_slug(),
view_type,
view.title,
)
r += htmltext('</li>')
r += htmltext('</ul></fieldset>')
return r.getvalue()
def get_default_filters(self, mode):

View File

@ -2196,10 +2196,6 @@ div.mail-body {
}
}
#sidebar-custom-views .active {
font-weight: bold;
}
.snapshots-table {
table-layout: fixed;
}
@ -2212,8 +2208,24 @@ p.snapshots-navigation {
text-align: center;
}
#sidebar-custom-views .as-data-source {
font-weight: normal;
.sidebar-custom-views {
.active {
font-weight: bold;
}
.datasource-views {
list-style: none;
}
}
fieldset.sidebar-custom-datasource-views {
margin: 0;
padding: 0;
border: 0;
legend {
padding-left: 25px;
}
ul {
margin-top: 0;
}
}
.section > h3.mail-subject {
@ -2968,4 +2980,24 @@ div.fileinfo a.remove {
}
}
fieldset.foldable {
legend {
cursor: pointer;
&::after {
content: "";
font-size: 80%;
margin-left: 1ex;
transition: transform ease 0.1s;
transform: rotate(0deg);
display: inline-block;
}
}
&.folded {
> :not(legend) {
display: none;
}
legend::after {
transform: rotate(-90deg);
}
}
}