summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ishtar_common/static/js/ishtar.js160
-rw-r--r--ishtar_common/templates/base.html3
-rw-r--r--ishtar_common/templates/blocks/DataTables.html158
-rw-r--r--ishtar_common/views_item.py15
-rw-r--r--scss/custom.scss18
5 files changed, 291 insertions, 63 deletions
diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js
index ea0ccc516..a41b718a7 100644
--- a/ishtar_common/static/js/ishtar.js
+++ b/ishtar_common/static/js/ishtar.js
@@ -40,6 +40,7 @@ function get_previous_table_id(){}
var datatable_submit_search = function() {};
+var current_tab = "table";
var shortcut_url = '';
var show_shortcut_menu = false;
var alert_url = '';
@@ -48,6 +49,7 @@ var datatables_i18n;
var current_modal;
var default_search_vector;
var pin_search_url;
+var static_path = '/static/';
var datatables_default = {
"processing": true,
@@ -67,6 +69,8 @@ var datatables_static_default = {
"lengthMenu": [ 5, 10, 25, 50, 100 ]
};
+var show_msg = "Show";
+var entries_msg = "entries";
var activate_all_search_msg = "Searches in the shortcut menu deals with all items.";
var activate_own_search_msg = "Searches in the shortcut menu deals with only your items.";
var added_message = " items added.";
@@ -979,3 +983,159 @@ var dt_multi_enable_disable_submit_button = function(e, dt, type, indexes){
$("#validation-bar #submit_form").prop('disabled', true);
}
};
+
+var render_gallery = function(data_table, table_name, nb_select){
+ var html = '<label>' + show_msg;
+ var id_select = table_name + '-length_image';
+ html += ' <select name="' + id_select + '" id="id_' + id_select + '">';
+ var nb_rows = [5, 10, 25, 50, 100];
+ for (idx in nb_rows){
+ var nb = nb_rows[idx];
+ html += '<option value="' + nb + '"';
+ if (nb == nb_select) html += " selected='selected'";
+ html += '>' + nb + '</option>';
+ }
+ html += '</select> ' + entries_msg + '</label>';
+ html += "<div class='ishtar-gallery d-flex flex-wrap'>";
+
+ $.each(data_table["rows"], function(idx, data){
+ var image = "";
+ if ("main_image__image" in data){
+ image = data["main_image__image"];
+ } else {
+ image = static_path + "media/images/empty-image.png";
+ }
+ var link = data["link"];
+ var name = '';
+ if ("cached_label" in data){
+ name = data["cached_label"];
+ }
+ if ("name" in data){
+ name = data["name"];
+ }
+ html += '<div class="card m-2">';
+ html += '<a class="thumb-image" href="#">';
+ html += '<img class="card-img-top" src="' + image + '">';
+ html += '</a>';
+ html += '<div class="card-body">';
+ html += '<h4 class="card-title">' + link + " " + name + '</h4>';
+ html += "</div></div>";
+ });
+ html += "</div>";
+
+ /* pagination */
+ var page_total = data_table['total'];
+ var page_current = data_table['page'];
+ html += "<div class='dataTables_wrapper'><div class='dataTables_paginate'>";
+ html += '<ul class="image-pagination">';
+
+ var disabled = page_current == 1;
+ html += render_paginate_button(page_current - 1, page_current, "Previous",
+ disabled, " previous");
+ html += render_paginate_button(1, page_current);
+
+ var idx_page = 2;
+ if (page_current < 5){
+ while (idx_page <= 5){
+ if (idx_page <= page_total){
+ html += render_paginate_button(idx_page, page_current);
+ idx_page += 1;
+ }
+ }
+ if (page_total > 6){
+ html += render_paginate_button('...');
+ }
+ html += render_paginate_button(page_total, page_current);
+ } else {
+ html += render_paginate_button('...');
+ if (page_total < page_current + 2 &&
+ page_total > (page_current - 2)){
+ html += render_paginate_button(page_current - 3, page_current);
+ }
+ if (page_total < page_current + 3 &&
+ page_total > (page_current - 3)){
+ html += render_paginate_button(page_current - 2, page_current);
+ }
+ html += render_paginate_button(page_current - 1, page_current);
+ html += render_paginate_button(page_current, page_current);
+ if (page_total > page_current)
+ html += render_paginate_button(page_current + 1, page_current);
+ if (page_total < page_current + 3){
+ idx_page = page_current + 2;
+ while (idx_page <= page_total){
+ html += render_paginate_button(idx_page, page_current);
+ idx_page += 1;
+ }
+ } else {
+ html += render_paginate_button('...');
+ html += render_paginate_button(page_total, page_current);
+ }
+ }
+
+ disabled = page_current == page_total;
+ html += render_paginate_button(
+ page_current + 1, page_current, "Next", disabled, " next");
+
+ html += '</ul></div></div>';
+ return html;
+};
+
+var render_paginate_button = function(nb, current, label, disabled, extra_class){
+ if (!extra_class) extra_class = '';
+ if (nb == '...'){
+ disabled = true;
+ } else if (current == nb) {
+ extra_class += ' active';
+ }
+ if (disabled) extra_class += ' disabled';
+ if (!label) label = nb;
+
+ var html = '<li class="paginate_button page-item' + extra_class +'">';
+ html += '<a href="#" data-dt-idx="' + nb + '" tabindex="0" class="page-link">';
+ html += label + '</a></li>';
+ return html;
+};
+
+var current_image_page = 1;
+
+var register_image_paginate = function(){
+ $(".image-pagination .paginate_button a").click(function(){
+ current_image_page = $(this).attr('data-dt-idx');
+ gallery_submit_search();
+ });
+};
+
+var main_submit_search = function(){
+ if (current_tab == "table") datatable_submit_search();
+ if (current_tab == "gallery") gallery_submit_search();
+};
+
+var search_get_query_data = function(query_vars, table_name){
+ $("#id_search_vector").removeClass('input-progress');
+ if ($('.modal-progress').length > 0){
+ $('.modal-progress').modal('show');
+ }
+ var data = "";
+ for (idx in query_vars){
+ var key = query_vars[idx];
+ var item = jQuery("#id_" + key);
+ var val = null;
+ if (item.prop('type') == 'checkbox'){
+ if (item.prop('checked')){
+ var val = item.val();
+ }
+ } else {
+ var val = item.val();
+ }
+ if (val){
+ if (data) data += "&";
+ data += key + "=" + encodeURIComponent(val);
+ }
+ }
+ if (current_image_page && current_tab == "gallery"){
+ var id_select = "#id_" + table_name + '-length_image';
+ if (data) data += "&";
+ data += "start=" + ((current_image_page - 1) * $(id_select).val());
+ }
+ return data;
+};
diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html
index e5af101d5..c84083409 100644
--- a/ishtar_common/templates/base.html
+++ b/ishtar_common/templates/base.html
@@ -30,6 +30,7 @@
src="{{STATIC_URL}}datatables/i18n/{{LANGUAGE_CODE}}.js?ver={{VERSION}}"></script>
{{EXTRA_JS|safe}}
<script type='text/javascript'>
+ var static_path = "{{STATIC_URL}}";
var shortcut_url = '{% url "shortcut-menu" %}';
{% if DISPLAY_PIN_MENU %}var show_shortcut_menu = true;{% endif %}
var alert_url = '{% url "alert-list" %}';
@@ -47,6 +48,8 @@
var select_only_one_msg = "{% trans "Select only one item." %}";
var YES = "{% trans 'yes' %}";
var NO = "{% trans 'no' %}";
+ var show_msg = "{% trans "Show" %}";
+ var entries_msg = "{% trans "entries" %}";
var autorefresh_message_start = "{% trans 'Autorefresh start. The form is disabled.' %}";
var autorefresh_message_end = "{% trans 'Autorefresh end. The form is re-enabled.' %}";
</script>
diff --git a/ishtar_common/templates/blocks/DataTables.html b/ishtar_common/templates/blocks/DataTables.html
index 096650115..07725353c 100644
--- a/ishtar_common/templates/blocks/DataTables.html
+++ b/ishtar_common/templates/blocks/DataTables.html
@@ -27,50 +27,79 @@
</div>
</div>
-<div id="grid_{{name}}_meta_wrapper">
- <table id='grid_{{name}}' class="display" width="100%">
- <thead>
- <tr>
- <th></th>
- <th></th>{% for col in col_names %}
- <th>{{col}}</th>
- {% endfor %}</tr>
- </thead>
- </table>
-</div>
+<ul class="nav nav-tabs m-3">
+ <li class="nav-item">
+ <a class="nav-link active" id="tab-grid-{{name}}" data-toggle="tab"
+ href="#tab-content-grid-{{name}}" role="tab"
+ aria-controls="tab-content-grid-{{name}}" aria-selected="true">
+ {% trans "Table" %}
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="tab-gallery-{{name}}" data-toggle="tab"
+ href="#tab-content-gallery-{{name}}" role="tab"
+ aria-controls="tab-content-gallery-{{name}}" aria-selected="true">
+ {% trans "Gallery" %}
+ </a>
+ </li>
+</ul>
-<div id='foot_{{name}}' class="gridfooter row toolbar">
- <div class='col-md-2'>
- <div class="btn-group btn-group-sm" role="group">
- <button type='button' class="btn btn-secondary" data-toggle="modal"
- data-target="#modal_grid_{{name}}">
- {% trans "Expand table" %} <i class="fa fa-expand" aria-hidden="true"></i>
- </button>
- </div>
+
+<div class="tab-content">
+ <div class="tab-pane active"
+ id="tab-content-grid-{{name}}" role="tabpanel"
+ aria-labelledby="tab-grid-{{name}}">
+
+ <div id="grid_{{name}}_meta_wrapper">
+ <table id='grid_{{name}}' class="display" width="100%">
+ <thead>
+ <tr>
+ <th></th>
+ <th></th>{% for col in col_names %}
+ <th>{{col}}</th>
+ {% endfor %}</tr>
+ </thead>
+ </table>
</div>
- <div class='col-md-2'>
- <div class="btn-group btn-group-sm" role="group"
- aria-label="{% trans 'Export'%}">
- {% if source_full or extra_sources %}
- <a class="btn btn-secondary" href='{{source}}csv' target='_blank'
- title="{% trans 'Export as CSV - ' %}{% trans 'simple'%}">{% trans "Simple CSV" %}</a>
- {% if source_full %}<a class='btn btn-secondary' href='{{source_full}}csv' target='_blank' title="{% trans 'Export as CSV - full' %}">{% trans "CSV full" %}</a>{% endif %}
- {% for slug, name, extra_source in extra_sources %}
- <a class="btn btn-secondary" href='{{extra_source}}csv' target='_blank' title="{% trans 'Export as CSV - ' %}{{name}}">{{name}}</a>
- {% endfor %}
- {% else %}
- <a class="btn btn-secondary" href="{{source}}csv" target="_blank" title="{% trans 'Export as CSV' %}">{% trans "CSV" %}</a>
- {% endif %}
+
+ <div id='foot_{{name}}' class="gridfooter row toolbar">
+ <div class='col-md-2'>
+ <div class="btn-group btn-group-sm" role="group">
+ <button type='button' class="btn btn-secondary" data-toggle="modal"
+ data-target="#modal_grid_{{name}}">
+ {% trans "Expand table" %} <i class="fa fa-expand" aria-hidden="true"></i>
+ </button>
+ </div>
+ </div>
+ <div class='col-md-2'>
+ <div class="btn-group btn-group-sm" role="group"
+ aria-label="{% trans 'Export'%}">
+ {% if source_full or extra_sources %}
+ <a class="btn btn-secondary" href='{{source}}csv' target='_blank'
+ title="{% trans 'Export as CSV - ' %}{% trans 'simple'%}">{% trans "Simple CSV" %}</a>
+ {% if source_full %}<a class='btn btn-secondary' href='{{source_full}}csv' target='_blank' title="{% trans 'Export as CSV - full' %}">{% trans "CSV full" %}</a>{% endif %}
+ {% for slug, name, extra_source in extra_sources %}
+ <a class="btn btn-secondary" href='{{extra_source}}csv' target='_blank' title="{% trans 'Export as CSV - ' %}{{name}}">{{name}}</a>
+ {% endfor %}
+ {% else %}
+ <a class="btn btn-secondary" href="{{source}}csv" target="_blank" title="{% trans 'Export as CSV' %}">{% trans "CSV" %}</a>
+ {% endif %}
+ </div>
</div>
</div>
-</div>
-{% if multiple %}
-<input type="button" id="add_button_{{name}}" value="{% trans 'Add' %}"/>
-<ul id="selectmulti_{{name}}" class="selectmulti"></ul>
-{% endif %}
+ {% if multiple %}
+ <input type="button" id="add_button_{{name}}" value="{% trans 'Add' %}"/>
+ <ul id="selectmulti_{{name}}" class="selectmulti"></ul>
+ {% endif %}
-<input type="hidden" id="hidden_{{name}}" name="{{name}}"/>
+ <input type="hidden" id="hidden_{{name}}" name="{{name}}"/>
+ </div>
+ <div class="tab-pane active"
+ id="tab-content-gallery-{{name}}" role="tabpanel"
+ aria-labelledby="tab-gallery-{{name}}">
+ </div>
+</div>
<script type="text/javascript" language='javascript'>
$('#modal_grid_{{name}}').on('show.bs.modal', function (e) {
@@ -90,33 +119,41 @@ $('#modal_grid_{{name}}').on('hide.bs.modal', function (e) {
current_modal = null;
});
+$("#tab-gallery-{{name}}").click(function(){
+ current_tab = "gallery";
+ gallery_submit_search();
+});
+
+$("#tab-grid-{{name}}").click(function(){
+ current_tab = "table";
+ datatable_submit_search();
+});
+
var query_vars = new Array({{col_idx|safe}});
var selItems_{{sname}} = new Array();
+gallery_submit_search = function(){
+ var data = search_get_query_data(query_vars, "{{name}}");
+ var nb_select = jQuery("#id_{{name}}-length_image").val();
+ if (!nb_select) nb_select = 10;
+
+ var url = "{{source}}json-image?length=" + nb_select + "&submited=1&" + data;
+ $.getJSON(url, function(data) {
+ $("#tab-content-gallery-{{name}}").html(
+ render_gallery(data, "{{name}}", nb_select));
+ $("#id_{{name}}-length_image").change(gallery_submit_search);
+ register_image_paginate();
+ });
-datatable_submit_search = function(){
- $("#id_search_vector").removeClass('input-progress');
if ($('.modal-progress').length > 0){
- $('.modal-progress').modal('show');
- }
- var data = "";
- for (idx in query_vars){
- var key = query_vars[idx];
- var item = jQuery("#id_"+key);
- var val = null;
- if (item.prop('type') == 'checkbox'){
- if (item.prop('checked')){
- var val = item.val();
- }
- } else {
- var val = item.val();
- }
- if (val){
- if (data) data += "&";
- data += key + "=" + encodeURIComponent(val);
- }
+ $('.modal-progress').modal('hide');
}
+ return false;
+};
+
+datatable_submit_search = function(){
+ var data = search_get_query_data(query_vars, "{{name}}");
var mygrid = jQuery("#grid_{{name}}");
var url = "{{source}}?submited=1&" + data;
datatable_{{sname}}.ajax.url(url).load();
@@ -134,8 +171,11 @@ datatable_submit_search = function(){
return false;
};
+
jQuery(document).ready(function(){
- jQuery("#search_{{name}}").click(datatable_submit_search);
+ jQuery("#search_{{name}}").click(
+ main_submit_search
+ );
var base_source = "{{source}}";
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 6f4abdee9..dee4d2ffb 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -1003,6 +1003,9 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
if data_type == "json":
EMPTY = '[]'
+ if data_type not in ('json', 'csv', 'json-image'):
+ return HttpResponse(EMPTY, content_type='text/plain')
+
model_to_check = model
if model_for_perms:
model_to_check = model_for_perms
@@ -1301,13 +1304,16 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
if col in model.CONTEXTUAL_TABLE_COLS[contxt]:
query_table_cols[idx] = \
model.CONTEXTUAL_TABLE_COLS[contxt][col]
- if full == 'shortcut':
+ if full == 'shortcut' or data_type == 'json-image':
if model.SLUG == "warehouse":
query_table_cols = ['name']
table_cols = ['name']
else:
query_table_cols = ['cached_label']
table_cols = ['cached_label']
+ if data_type == 'json-image':
+ query_table_cols.append('main_image__image')
+ table_cols.append('main_image__image')
# manage sort tables
manual_sort_key = None
@@ -1371,7 +1377,7 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
# pager management
start, end = 0, None
page_nb = 1
- if row_nb and data_type == "json":
+ if row_nb and data_type.startswith("json"):
try:
start = int(request_items.get('start'))
page_nb = start / row_nb + 1
@@ -1478,11 +1484,12 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
"onclick='load_window(\"%s\")'>" \
"<i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i></a>"
link_ext_template = '<a href="{}" target="_blank">{}</a>'
- if data_type == "json":
+ if data_type.startswith("json"):
rows = []
for data in datas:
try:
- lnk = link_template % reverse('show-' + default_name,
+ lnk_template = link_template
+ lnk = lnk_template % reverse('show-' + default_name,
args=[data[0], ''])
except NoReverseMatch:
logger.warning(
diff --git a/scss/custom.scss b/scss/custom.scss
index 56dbffab6..d0cbdc6eb 100644
--- a/scss/custom.scss
+++ b/scss/custom.scss
@@ -278,6 +278,10 @@ textarea {
background-color: $gray-400;
}
+.form h4.card-title {
+ background-color: transparent;
+}
+
.collapse-form .card,
.collapse-form .card-header{
border-radius: 0;
@@ -521,6 +525,20 @@ ul.compact{
display: none;
}
+.ishtar-gallery .card{
+ width: 200px;
+}
+
+.thumb-image{
+ display: block;
+ position:relative;
+ overflow:hidden;
+ padding-bottom:100%;
+}
+.thumb-image img{
+ position:absolute;
+}
+
/* lightgallery */
.lightgallery-captions{