Skip to content

Commit b45fb9f

Browse files
committed
Merge branch 'release/v1.2'
2 parents f17bf6a + 8a5ec47 commit b45fb9f

39 files changed

+1185
-602
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.2.0] - 2023-10-10
6+
- Add ``get_slick_reporting_media`` and ``get_charts_media`` templatetags
7+
- Add `get_group_by_custom_querysets` hook to ReportView
8+
- Enhance and document adding export options and customizing the builtin export to csv button
9+
- Enhance and document adding custom buttons to the report page
10+
- Enhance and document adding a new chart engine
11+
- Fix in SlickReportingListView
12+
- Move all css and js resources to be handled by `Media` governed by `settings.SLICK_REPORTING_SETTINGS`
13+
14+
515
## [1.1.1] - 2023-09-25
616
- Change settings to be a dict , adding support JQUERY_URL and FONT AWESOME customization #79 & #81
717
- Fix issue with chartjs not being loaded #80

demo_proj/demo_app/helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939
("crosstab-report-with-time-series", reports.CrossTabWithTimeSeries),
4040
]
4141
OTHER = [
42+
("highcharts-examples", reports.HighChartExample),
4243
("chartjs-examples", reports.ChartJSExample),
44+
("apexcharts-examples", reports.ProductSalesApexChart),
45+
("custom-export", reports.CustomExportReport),
46+
("form-initial", reports.ReportWithFormInitial),
4347
]
4448

4549

demo_proj/demo_app/reports.py

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22

33
from django.db.models import Sum, Q
4+
from django.http import HttpResponse
45
from django.utils.translation import gettext_lazy as _
56

67
from slick_reporting.fields import ComputationField
@@ -170,9 +171,10 @@ class LastTenSales(ListReportView):
170171
report_model = SalesTransaction
171172
report_title = "Last 10 sales"
172173
date_field = "date"
173-
filters = ["client"]
174+
filters = ["product", "client", "date"]
174175
columns = [
175-
"product",
176+
"product__name",
177+
"client__name",
176178
"date",
177179
"quantity",
178180
"price",
@@ -607,3 +609,92 @@ class ChartJSExample(TimeSeriesReport):
607609
# plot_total=True,
608610
),
609611
]
612+
613+
614+
class HighChartExample(ChartJSExample):
615+
chart_engine = "highcharts"
616+
617+
618+
class ProductSalesApexChart(ReportView):
619+
report_title = _("Product Sales Apex Charts")
620+
report_model = SalesTransaction
621+
date_field = "date"
622+
group_by = "product"
623+
chart_engine = "apexcharts"
624+
template_name = "demo/apex_report.html"
625+
626+
columns = [
627+
"name",
628+
ComputationField.create(
629+
method=Sum,
630+
field="value",
631+
name="value__sum",
632+
verbose_name="Total sold $",
633+
is_summable=True,
634+
),
635+
]
636+
637+
# Charts
638+
chart_settings = [
639+
Chart(
640+
"Total sold $",
641+
type="pie",
642+
data_source=["value__sum"],
643+
title_source=["name"],
644+
),
645+
Chart(
646+
"Total sold $",
647+
type="bar",
648+
data_source=["value__sum"],
649+
title_source=["name"],
650+
),
651+
Chart(
652+
"A custom Entry Point $",
653+
type="bar",
654+
data_source=["value__sum"],
655+
title_source=["name"],
656+
entryPoint="displayChartCustomEntryPoint",
657+
),
658+
]
659+
660+
661+
class CustomExportReport(GroupByReport):
662+
report_title = _("Custom Export Report")
663+
export_actions = ["export_pdf"]
664+
665+
def export_pdf(self, report_data):
666+
return HttpResponse(f"Dummy PDF Exported \n {report_data}")
667+
668+
export_pdf.title = _("Export PDF")
669+
export_pdf.css_class = "btn btn-secondary"
670+
671+
def export_csv(self, report_data):
672+
return super().export_csv(report_data)
673+
674+
export_csv.title = _("My Custom CSV export Title")
675+
export_csv.css_class = "btn btn-primary"
676+
677+
678+
class ReportWithFormInitial(ReportView):
679+
report_title = _("Report With Form Initial")
680+
report_model = SalesTransaction
681+
date_field = "date"
682+
group_by = "product"
683+
684+
columns = [
685+
"name",
686+
ComputationField.create(
687+
method=Sum,
688+
field="value",
689+
name="value__sum",
690+
verbose_name="Total sold $",
691+
is_summable=True,
692+
),
693+
]
694+
695+
def get_initial(self):
696+
from .models import Client
697+
698+
initial = super().get_initial()
699+
initial["client_id"] = [Client.objects.first().pk, Client.objects.last().pk]
700+
return initial

demo_proj/demo_proj/settings.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"django.contrib.sessions",
3838
"django.contrib.messages",
3939
"django.contrib.staticfiles",
40-
4140
"demo_app",
4241
"crispy_forms",
4342
"crispy_bootstrap5",
@@ -130,3 +129,13 @@
130129

131130
CRISPY_TEMPLATE_PACK = "bootstrap5"
132131
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
132+
133+
SLICK_REPORTING_SETTINGS = {
134+
"CHARTS": {
135+
"apexcharts": {
136+
"entryPoint": "DisplayApexPieChart",
137+
"js": ("https://cdn.jsdelivr.net/npm/apexcharts", "slick_reporting/slick_reporting.chartsjs.js"),
138+
"css": {"all": ("https://cdn.jsdelivr.net/npm/apexcharts/dist/apexcharts.min.css",)},
139+
},
140+
},
141+
}

demo_proj/templates/dashboard.html

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,7 @@
33
{% block page_title %} Dashboard {% endblock %}
44
{% block meta_page_title %} Dashboard {% endblock %}
55

6-
{% block extrajs %}
7-
{% include "slick_reporting/js_resources.html" %}
8-
{# make sure to have the js_resources added to the dashboard page #}
96

10-
<script>
11-
function custom_js_callback(data, $elem) {
12-
// data is the json response from the server
13-
// $elem is the jquery object of the element `[data-report-widget]` that the report is attached to.
14-
15-
console.info(data);
16-
console.info($elem);
17-
$('#responsePre').text(JSON.stringify(data, null, 4));
18-
}
19-
20-
</script>
21-
{% endblock %}
227
{% block content %}
238
<div class="row row-deck row-cards">
249
<div class="col-lg-6">
@@ -51,4 +36,26 @@
5136

5237
</div>
5338

39+
{% endblock %}
40+
41+
{% block extrajs %}
42+
{% include "slick_reporting/js_resources.html" %}
43+
{# make sure to have the js_resources added to the dashboard page #}
44+
45+
{% get_charts_media "all" %}
46+
{# make sure to add all charts needed media, here the "all" arguments add all charts media to the page, #}
47+
{# You can skip it and add needed media by hand #}
48+
49+
50+
<script>
51+
function custom_js_callback(data, $elem) {
52+
// data is the json response from the server
53+
// $elem is the jquery object of the element `[data-report-widget]` that the report is attached to.
54+
55+
console.info(data);
56+
console.info($elem);
57+
$('#responsePre').text(JSON.stringify(data, null, 4));
58+
}
59+
60+
</script>
5461
{% endblock %}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{% extends "slick_reporting/report.html" %}
2+
{% load slick_reporting_tags %}
3+
4+
{% block content %}
5+
{{ block.super }}
6+
7+
{% endblock %}
8+
9+
{% block extrajs %}
10+
{{ block.super }}
11+
12+
<script>
13+
14+
let chart = null;
15+
16+
function displayChartCustomEntryPoint(data, $elem, chartOptions) {
17+
alert("This is a custom entry point for displaying charts. " +
18+
"Check the console for the sent arguments")
19+
console.log("data:", data);
20+
console.log("$elem:", $elem);
21+
console.log("chartOptions:", chartOptions);
22+
}
23+
24+
function DisplayApexPieChart(data, $elem, chartOptions) {
25+
let legendAndSeries = $.slick_reporting.chartsjs.getGroupByLabelAndSeries(data, chartOptions);
26+
let options = {}
27+
if (chartOptions.type === "pie") {
28+
options = {
29+
series: legendAndSeries.series,
30+
chart: {
31+
type: "pie",
32+
height: 350
33+
},
34+
labels: legendAndSeries.labels,
35+
};
36+
} else {
37+
options = {
38+
chart: {
39+
type: 'bar'
40+
},
41+
series: [{
42+
name: 'Sales',
43+
data: legendAndSeries.series
44+
}],
45+
xaxis: {
46+
categories: legendAndSeries.labels,
47+
}
48+
}
49+
}
50+
51+
try {
52+
// destroy old chart, if any
53+
chart.destroy();
54+
} catch (e) {
55+
// do nothing
56+
}
57+
58+
chart = new ApexCharts($elem[0], options);
59+
chart.render();
60+
61+
}
62+
</script>
63+
64+
{% endblock %}

demo_proj/templates/menu.html

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,21 @@
163163
</div>
164164
</li>
165165

166+
<li class="nav-item">
167+
<a class="nav-link" href="{% url "highcharts-examples" %}">
168+
<span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
169+
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
170+
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
171+
stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path
172+
d="M5 12l-2 0l9 -9l9 9l-2 0"/><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"/><path
173+
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
174+
</span>
175+
<span class="nav-link-title">
176+
HighCharts
177+
</span>
178+
</a>
179+
</li>
180+
166181
<li class="nav-item">
167182
<a class="nav-link" href="{% url "chartjs-examples" %}">
168183
<span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
@@ -177,5 +192,47 @@
177192
</span>
178193
</a>
179194
</li>
195+
<li class="nav-item">
196+
<a class="nav-link" href="{% url "apexcharts-examples" %}">
197+
<span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
198+
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
199+
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
200+
stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path
201+
d="M5 12l-2 0l9 -9l9 9l-2 0"/><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"/><path
202+
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
203+
</span>
204+
<span class="nav-link-title">
205+
Apex Chart Demo
206+
</span>
207+
</a>
208+
</li>
209+
<li class="nav-item">
210+
<a class="nav-link" href="{% url "custom-export" %}">
211+
<span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
212+
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
213+
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
214+
stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path
215+
d="M5 12l-2 0l9 -9l9 9l-2 0"/><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"/><path
216+
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
217+
</span>
218+
<span class="nav-link-title">
219+
Custom Export
220+
</span>
221+
</a>
222+
</li>
180223

224+
<li class="nav-item">
225+
<a class="nav-link" href="{% url "form-initial" %}">
226+
<span class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/home -->
227+
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
228+
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
229+
stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path
230+
d="M5 12l-2 0l9 -9l9 9l-2 0"/><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"/><path
231+
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
232+
</span>
233+
<span class="nav-link-title">
234+
Form initial
235+
</span>
236+
</a>
237+
</li>
181238
</ul>

0 commit comments

Comments
 (0)