users weekly stats as bar-chart in dashboard (#847)

This commit is contained in:
Kevin Papst
2019-06-13 18:38:49 +02:00
committed by GitHub
parent e1f862507e
commit 3311f17bbb
96 changed files with 2754 additions and 846 deletions

View File

@@ -0,0 +1,97 @@
<div class="row">
<div class="col-md-12">
<div class="box">
{#
<div class="box-header with-border">
<h3 class="box-title">{{ title|trans }}</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<div class="btn-group">
<button type="button" class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-wrench"></i></button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
#}
<div class="box-body">
<div class="row">
<div class="col-md-12">
{{ render_widget(widgets.0) }}
</div>
{#
<div class="col-md-4">
<p class="text-center">
<strong>Goal Completion</strong>
</p>
<div class="progress-group">
<span class="progress-text">Add Products to Cart</span>
<span class="progress-number"><b>160</b>/200</span>
<div class="progress sm">
<div class="progress-bar progress-bar-aqua" style="width: 80%"></div>
</div>
</div>
<div class="progress-group">
<span class="progress-text">Complete Purchase</span>
<span class="progress-number"><b>310</b>/400</span>
<div class="progress sm">
<div class="progress-bar progress-bar-red" style="width: 80%"></div>
</div>
</div>
<div class="progress-group">
<span class="progress-text">Visit Premium Page</span>
<span class="progress-number"><b>480</b>/800</span>
<div class="progress sm">
<div class="progress-bar progress-bar-green" style="width: 80%"></div>
</div>
</div>
<div class="progress-group">
<span class="progress-text">Send Inquiries</span>
<span class="progress-number"><b>250</b>/500</span>
<div class="progress sm">
<div class="progress-bar progress-bar-yellow" style="width: 80%"></div>
</div>
</div>
</div>
#}
</div>
</div>
{% if widgets|length > 1 %}
<div class="box-footer">
<div class="row">
{% set width = (widgets|length) - 1 %}
{% set rawWidth = 12 / width %}
{% set columnWidth = rawWidth|round(0, 'floor') %}
{% for widget in widgets|slice(1, width) %}
{% set data = widget.data %}
{% if widget.option('dataType') == 'duration' %}
{% set data = widget.data|duration %}
{% elseif widget.option('dataType') == 'money' %}
{% set data = widget.data|money %}
{% endif %}
<div class="col-sm-{{ columnWidth }} col-xs-{{ columnWidth * 2 }}">
<div class="description-block border-right">
{#<span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 17%</span>#}
{#<span class="description-percentage text-yellow"><i class="fa fa-caret-left"></i> 0%</span>#}
{#<span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 20%</span>#}
{#<span class="description-percentage text-red"><i class="fa fa-caret-down"></i> 18%</span>#}
<h5 class="description-header">{{ data }}</h5>
<span class="description-text">{{ widget.title|trans }}</span>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>
</div>

View File

@@ -0,0 +1,20 @@
{% import "macros/widgets.html.twig" as widgets %}
{% if not title is empty %}
{{ widgets.page_header(title) }}
{% endif %}
{% set width = widgets|length %}
{% set rawWidth = 12 / width %}
{% set columnWidth = rawWidth|round(0, 'floor') %}
<div class="row">
{% for widget in widgets %}
{% set columnSize = columnWidth %}
{% if width == 5 and (loop.first or loop.last) %}
{% set columnSize = columnWidth + 1 %}
{% endif %}
<div class="col-md-{{ columnSize }} col-sm-{{ columnSize * 2 }} col-xs-{{ columnSize * 4 }}">
{{ render_widget(widget) }}
</div>
{% endfor %}
</div>

View File

@@ -0,0 +1,28 @@
{% set url = null %}
{% if options.route is defined %}
{% set url = path(options.route, options.routeOptions|default([])) %}
{% endif %}
<div class="info-box">
<span class="info-box-icon bg-{{ options.color|default('green') }}"><i class="{{ options.icon|icon(options.icon) }}"></i></span>
<div class="info-box-content">
{% if not url is empty %}<a href="{{ url }}" class="small-box-footer">{% endif %}
<span class="info-box-text">{{ title|trans }}</span>
<span class="info-box-number">
{% if data is iterable %}
{{ 'Invalid data' }}
{% else %}
{% block widget_data %}
{% if options.dataType == 'duration' %}
{% set data = data|duration %}
{% elseif options.dataType == 'money' %}
{% set data = data|money %}
{% endif %}
{{ data }}
{% endblock %}
{% endif %}
</span>
{% if not url is empty %}</a>{% endif %}
</div>
</div>

View File

@@ -0,0 +1,95 @@
{% set type = options.type|default('bar') %}
{% set chart_id = options.id %}
{% set backgroundColor = kimai_context.chart.background_color %}
{% set borderColor = kimai_context.chart.border_color %}
{% set gridColor = kimai_context.chart.grid_color %}
{% set colors = options.color|default('')|split(';') %}
{% if colors.0 is defined and not colors.0 is empty %}
{% set backgroundColor = colors.0 %}
{% set borderColor = colors.0 %}
{% if colors.1 is defined and not colors.1 is empty %}
{% set borderColor = colors.1 %}
{% endif %}
{% endif %}
{{ encore_entry_link_tags('chart') }}
{{ encore_entry_script_tags('chart') }}
{% if not title is empty %}
<p class="text-center">
<strong>
{{ title|trans }}
</strong>
</p>
{% endif %}
<div class="chart">
<canvas id="{{ chart_id }}" style="height: {{ kimai_context.chart.height }}px;"></canvas>
</div>
<script type="text/javascript">
document.addEventListener('kimai.initialized', function() {
new Chart(
document.getElementById('{{ chart_id }}').getContext('2d'), {
type: '{{ type }}',
data: {
labels: [
{% for day in data -%}
moment('{{ day.day|date_format(constant('\DateTime::ISO8601')) }}').format('ll')
{% if not loop.last %},{% endif -%}
{%- endfor %}
],
datasets: [
{
backgroundColor: '{{ backgroundColor }}',
borderColor: '{{ borderColor }}',
data: [
{% for day in data -%}
{{ (day.totalDuration / 3600)|number_format(2, '.', '') }}
{%- if not loop.last %},{% endif -%}
{%- endfor %}
],
realData: [
{% for day in data -%}
'{{ day.totalDuration|duration }}'
{%- if not loop.last %},{% endif -%}
{%- endfor %}
]
}
]
},
options: {
maintainAspectRatio: true,
responsive: true,
legend: false,
barPercentage: 0.5,
categoryPercentage: 0.9,
scales: {
xAxes: [{
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
beginAtZero: true
},
gridLines: {
display: true,
color: '{{ gridColor }}',
lineWidth: 1
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
}
}
}
}
}
);
});
</script>

View File

@@ -0,0 +1,33 @@
{% set url = null %}
{% if options.route is defined %}
{% set url = path(options.route, options.routeOptions|default([])) %}
{% endif %}
<div class="small-box bg-{{ options.color|default('green') }}">
<div class="inner">
<h3>
{% if data is iterable %}
{{ 'Invalid data' }}
{% else %}
{% block widget_data %}
{% if options.dataType == 'duration' %}
{% set data = data|duration %}
{% elseif options.dataType == 'money' %}
{% set data = data|money %}
{% endif %}
{{ data }}
{% endblock %}
{% endif %}
<sup style="font-size: 20px">{{ unit|default('') }}</sup>
</h3>
<p>{{ title|trans }}</p>
</div>
<div class="icon">
<i class="{{ options.icon|icon(options.icon) }}"></i>
</div>
{% if not url is empty %}
<a href="{{ url }}" class="small-box-footer">
{{ 'more.info.link'|trans }}
</a>
{% endif %}
</div>

View File

@@ -0,0 +1,98 @@
{% set backgroundColor = kimai_context.chart.background_color %}
{% set borderColor = kimai_context.chart.border_color %}
{% set gridColor = kimai_context.chart.grid_color %}
{% set colors = options.color|default('')|split(';') %}
{% set type = options.type|default('line') %}
{% if type not in ['line', 'bar'] %}
{% set type = 'line' %}
{% endif %}
{% if not title is empty %}
<p class="text-center">
<strong>
{{ title|trans }}
</strong>
</p>
{% endif %}
<div class="chart">
<canvas id="timeChart" style="height: {{ kimai_context.chart.height }}px;"></canvas>
</div>
<script type="text/javascript">
document.addEventListener('kimai.initialized', function() {
new Chart(
document.getElementById('timeChart').getContext('2d'), {
type: '{{ type }}',
data: {
labels: moment.months(),
datasets: [
{% for yearName, year in data %}
{% set yearBackgroundColor = backgroundColor %}
{% set yearBorderColor = borderColor %}
{% if colors[loop.index-1] is defined %}
{% set yearColors = colors[loop.index-1]|split('|') %}
{% if yearColors.0 is defined and not yearColors.0 is empty %}
{% set yearBackgroundColor = yearColors.0 %}
{% set yearBorderColor = yearColors.0 %}
{% if yearColors.1 is defined and not yearColors.1 is empty %}
{% set yearBorderColor = yearColors.1 %}
{% endif %}
{% endif %}
{% endif %}
{
label : '{{ yearName }}',
backgroundColor : '{{ yearBackgroundColor }}',
borderColor : '{{ yearBorderColor }}',
pointRadius : 2,
borderWidth : 1,
pointHitRadius : 10,
lineTension : 0.3,
data : [
{% for month in year.months %}
{{ (month.totalDuration / 3600)|number_format(2, '.', '') }}
{% if not loop.last %},{% endif %}
{% endfor %}
],
realData : [
{% for month in year.months %}
'{{ month.totalDuration|duration }}'
{% if not loop.last %},{% endif %}
{% endfor %}
]
}
{% if not loop.last %},{% endif %}
{% endfor %}
]
},
options: {
maintainAspectRatio: true,
responsive: true,
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
display: true,
color: '{{ gridColor }}',
lineWidth: 1
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].realData[tooltipItem.index];
}
}
}
}
}
);
});
</script>