Skip to content

Commit

Permalink
Feature/296 data-id in table row (#297)
Browse files Browse the repository at this point in the history
* updated pagination block, added top_pagination block.

* removed unused imports

* fixed first/last pagination indexes

* added list_actions block

* fixed comment and naming

* fixes corresponding to PR comments

* fixed defining ListMixin attrs.
Renamed bottom_pagination

* fixed flak8, test

* added basic tests

* updated changelog

* #296 added data attribute data-id in base_data_table row to easily distinct rows

* #296 changed list_items content_data to dict-like structure.
  • Loading branch information
Gooliver2 authored and mmarcos committed May 30, 2018
1 parent f6e9989 commit 3ca8165
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 76 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Always reference the ticket number at the end of the issue description.


## Pending

### Added

- added data attribute data-id in base_data_table row to easily distinct rows


## 1.1.1

### Changed
Expand Down
33 changes: 22 additions & 11 deletions arctic/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,12 @@ def get_list_items(self, objects): # noqa: C901

for obj in objects:
field_classes = self.get_field_classes(obj)
row = []
row = {
'id': getattr(obj, self.primary_key), # for row data id attr
'fields': [],
'actions': [],
'sorting_field': None
}

for field_name in fields:
field = {'type': 'field', 'field': field_name}
Expand All @@ -464,16 +469,18 @@ def get_list_items(self, objects): # noqa: C901
field_links[field_name], obj)
if field_name in field_classes:
field['class'] = field_classes[field_name]
row.append(field)
row['fields'].append(field)

actions = self._get_field_actions(obj)
if actions:
row.append(actions)
row['actions'].append(actions)
self.has_action_links = True
if self.sorting_field:
sort = {'type': 'sorting',
'id': getattr(obj, self.primary_key),
'value': getattr(obj, self.sorting_field)}
row.insert(0, sort)
row['sorting_field'] = {
'type': 'sorting',
'id': getattr(obj, self.primary_key),
'value': getattr(obj, self.sorting_field)
}
items.append(row)
return items

Expand Down Expand Up @@ -643,20 +650,24 @@ def get_list_items(self, objects):
else field)
for obj in objects:
field_classes = self.get_field_classes(obj)
row = []
row = {
'id': getattr(obj, 'id', ''),
'fields': [],
'actions': [],
}
for field_name in fields:
field = {'field': field_name, 'type': 'field'}
field['value'] = self.get_field_value(field_name, obj)
if field_name in field_links.keys():
field['url'] = self._reverse_field_link(
field_links[field_name], obj, self.primary_key)
field_links[field_name], obj)
if field_name in field_classes:
field['class'] = field_classes[field_name]
row.append(field)
row['fields'].append(field)
items.append(row)
actions = self._get_field_actions(obj)
if actions:
row.append(actions)
row['actions'].append(actions)
self.has_action_links = True
return items

Expand Down
84 changes: 42 additions & 42 deletions arctic/templates/arctic/partials/base_data_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,44 +100,51 @@ <h4 class="arctic-card__title">
{% endif %}
</tr>
</thead>
<tbody {% if list_items.0.0.type == 'sorting' %}data-sorting-url="{{ sorting_url }}"{% endif %}>
<tbody {% if list_items.0.sorting_field %}data-sorting-url="{{ sorting_url }}"{% endif %}>
{% for row in list_items %}
<tr>
{% for column in row %}
{% if column.type == 'field' %}
<td {% if column.class %}class="{{ column.class }}"{%endif%}>
{% if column.url %}
<a href="{{ column.url }}"{% if list_items.0.0.type == 'sorting' %}style="display:block;"{% endif %}
{% if column.confirm %}
data-toggle="modal"
data-target="#confirm-dialog"
data-confirm-title="{{ column.confirm.title }}"
data-confirm-message="{{ column.confirm.message|linebreaks }}"
data-confirm-ok="{{ column.confirm.ok }}"
data-confirm-cancel="{{ column.confirm.cancel }}"
data-confirm-class="{{ column.confirm.class }}"
{% endif %}
>
{% endif %}
{% if column.value|typename != 'list' %}
{{ column.value|default_if_none:"" }}
{% else %}
{% for item in column.value %}
<span class="list-tag">{{ item }}</span>
{% endfor %}
{% endif %}
{% if column.url %}
</a>
<tr {% if row.id %} data-id="{{ row.id }}" {% endif %}>
{% if row.sorting_field %}
<td class="drag-cell">
<div class="list-actions drag-handle show-on-hover">
<i data-sorting-key="{{ row.sorting_field.id }}" data-sorting-value="{{ column.value }}" class="fa fa-bars"></i>
</div>
</td>
{% endif %}
{% for column in row.fields %}
<td {% if column.class %}class="{{ column.class }}"{%endif%}>
{% if column.url %}
<a href="{{ column.url }}"{% if list_items.0.0.type == 'sorting' %}style="display:block;"{% endif %}
{% if column.confirm %}
data-toggle="modal"
data-target="#confirm-dialog"
data-confirm-title="{{ column.confirm.title }}"
data-confirm-message="{{ column.confirm.message|linebreaks }}"
data-confirm-ok="{{ column.confirm.ok }}"
data-confirm-cancel="{{ column.confirm.cancel }}"
data-confirm-class="{{ column.confirm.class }}"
{% endif %}
</td>
{% elif column.type == 'actions' %}
<td>
>
{% endif %}
{% if column.value|typename != 'list' %}
{{ column.value|default_if_none:"" }}
{% else %}
{% for item in column.value %}
<span class="list-tag">{{ item }}</span>
{% endfor %}
{% endif %}
{% if column.url %}
</a>
{% endif %}
</td>
{% endfor %}
{% for action in row.actions %}
<td>
{% block list_actions %}
<div class="list-actions">
{% for link in column.actions %}
<a href="{{ link.url }}" class="action-{{ link.label }} btn btn-secondary btn-sm show-on-hover" title="{{ link.label|capfirst }}"
{% for link in action.actions %}
<a href="{{ link.url }}" class="action-{{ link.label }} btn btn-secondary btn-sm show-on-hover" title="{{ link.label|capfirst }}"
{% if link.confirm %}
data-toggle="modal"
data-toggle="modal"
data-target="#confirm-dialog"
data-confirm-title="{{ link.confirm.title }}"
data-confirm-message="{{ link.confirm.message|linebreaks }}"
Expand All @@ -154,16 +161,9 @@ <h4 class="arctic-card__title">
</a>
{% endfor %}
<div class="list-actions-placeholder"></div>
{% endblock %}
</div>
</td>
{% elif column.type == 'sorting' %}
<td class="drag-cell">
<div class="list-actions drag-handle show-on-hover">
<i data-sorting-key="{{ column.id }}" data-sorting-value="{{ column.value }}" class="fa fa-bars"></i>
</div>
</td>
{% endif %}
{% endblock %}
</td>
{% endfor %}
</tr>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_articles.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
def test_article_list(admin_client, article):
response = admin_client.get(reverse('articles:list'))
assert response.status_code == 200
list_items = response.context['list_items'][0]
list_items = response.context['list_items'][0]['fields']
item_dict = {}
for item in list_items:
try:
Expand Down
5 changes: 3 additions & 2 deletions tests/test_field_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ def test_field_classes(self, admin_client):
ArticleFactory(published=False)
response = self._request(admin_client)

assert response.context_data['list_items'][0][2]['class'] == 'online'
assert response.context_data['list_items'][1][2]['class'] == 'offline'
list_items = response.context_data['list_items']
assert list_items[0]['fields'][2]['class'] == 'online'
assert list_items[1]['fields'][2]['class'] == 'offline'
35 changes: 21 additions & 14 deletions tests/test_generics/test_list_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ def test_single_item(self, admin_client):
article = ArticleFactory()
response = self._request(admin_client)
self._assert_list_items_len(response, 1)
field = response.context_data['list_items'][0][0]['field']
assert response.context_data['list_items'][0][0]['value'] == \
getattr(article, field)
lst_items = response.context_data['list_items']
field = lst_items[0]['fields'][0]['field']
assert lst_items[0]['fields'][0]['value'] == getattr(article, field)

def test_paginated_items(self, admin_client):
"""
Expand Down Expand Up @@ -95,8 +95,10 @@ def test_simple_search_form(self, admin_client):
# search filled, filter content
response = admin_client.get(reverse('articles:list'),
{'search': 'le1'})
assert len(response.context_data['list_items']) == 1
assert response.context_data['list_items'][0][0]['value'] == 'title1'

list_items = response.context_data['list_items']
assert len(list_items) == 1
assert list_items[0]['fields'][0]['value'] == 'title1'

def test_advanced_search_form(self, admin_client):
"""
Expand All @@ -113,8 +115,9 @@ def test_advanced_search_form(self, admin_client):
# search filled, filter content
response = admin_client.get(reverse('articles:list'),
{'description': 'tion2'})
assert len(response.context_data['list_items']) == 1
assert response.context_data['list_items'][0][0]['value'] == 'title2'
list_items = response.context_data['list_items']
assert len(list_items) == 1
assert list_items[0]['fields'][0]['value'] == 'title2'

def test_simple_search_form_quick_filters(self, admin_client):
"""
Expand All @@ -133,12 +136,14 @@ def test_simple_search_form_quick_filters(self, admin_client):

response = admin_client.get(reverse('articles:list'),
{'published': 'published'})
assert len(response.context_data['list_items']) == 1
assert response.context_data['list_items'][0][0]['value'] == 'title1'
list_items = response.context_data['list_items']
assert len(list_items) == 1
assert list_items[0]['fields'][0]['value'] == 'title1'

response = admin_client.get(reverse('articles:list'),
{'published': 'drafts'})
assert response.context_data['list_items'][0][0]['value'] == 'title2'
list_items = response.context_data['list_items']
assert list_items[0]['fields'][0]['value'] == 'title2'

def test_field_actions(self, admin_client):
ArticleFactory(title='title1', description='description1',
Expand All @@ -148,8 +153,9 @@ def test_field_actions(self, admin_client):

response = admin_client.get(reverse('articles:list'),
{'description': ''})
assert len(response.context_data['list_items'][0][-1]['actions']) == 1
assert len(response.context_data['list_items'][1][-1]['actions']) == 2
list_items = response.context_data['list_items']
assert len(list_items[0]['actions'][-1]['actions']) == 1
assert len(list_items[1]['actions'][-1]['actions']) == 2

def test_field_actions_allowing(self, admin_client):
def get_field_actions(self, obj):
Expand All @@ -171,5 +177,6 @@ def get_field_actions(self, obj):

response = admin_client.get(reverse('articles:list'),
{'description': ''})
assert len(response.context_data['list_items'][0][-1]['actions']) == 1
assert len(response.context_data['list_items'][1][-1]['actions']) == 2
list_items = response.context_data['list_items']
assert len(list_items[0]['actions'][-1]['actions']) == 1
assert len(list_items[1]['actions'][-1]['actions']) == 2
4 changes: 2 additions & 2 deletions tests/test_generics/test_ordering.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ def test_virtual_ordering_field(self, admin_client):
assert lst_headers[3]['order_url'] == '/articles/?order=category__name'
assert lst_headers[3]['order_direction'] == 'desc'
assert len(lst_items) == 2
assert lst_items[0][0]['value'] == 'Article 1'
assert lst_items[1][0]['value'] == 'Article 0'
assert lst_items[0]['fields'][0]['value'] == 'Article 1'
assert lst_items[1]['fields'][0]['value'] == 'Article 0'
8 changes: 4 additions & 4 deletions tests/test_virtual_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ def test_virtual_field(self, admin_client):
self._assert_list_items_len(response, 1)

item = response.context_data['list_items'][0]
assert item[0]['value'] == article.title
assert item[1]['value'] == article.description
assert item[3]['value'] == article.category.name
assert item['fields'][0]['value'] == article.title
assert item['fields'][1]['value'] == article.description
assert item['fields'][3]['value'] == article.category.name

def test_missing_virtual_field(self, admin_client):
"""
Expand All @@ -42,7 +42,7 @@ def test_missing_virtual_field(self, admin_client):
response = self._request(admin_client)

search_virtual_field = False
for field in response.context_data['list_items'][0]:
for field in response.context_data['list_items'][0]['fields']:
if field['type'] == 'field' and 'virtual_field' in field['field']:
search_virtual_field = True

Expand Down

0 comments on commit 3ca8165

Please sign in to comment.