new: [instance:home] Added statistics and highlight panel - WiP

pull/72/head
mokaddem 2021-09-06 11:17:25 +02:00
parent 6a68290561
commit 14e0fa90b3
6 changed files with 169 additions and 3 deletions

View File

@ -19,7 +19,9 @@ class InstanceController extends AppController
public function home()
{
$this->set('md', file_get_contents(ROOT . '/README.md'));
// $this->set('md', file_get_contents(ROOT . '/README.md'));
$statistics = $this->Instance->getStatistics();
$this->set('statistics', $statistics);
}
public function status()

View File

@ -4,6 +4,7 @@ namespace App\Model\Table;
use App\Model\Table\AppTable;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Validation\Validator;
use Migrations\Migrations;
@ -21,6 +22,47 @@ class InstanceTable extends AppTable
return $validator;
}
public function getStatistics($days=7): array
{
$models = ['Individuals', 'Organisations', 'Alignments', 'EncryptionKeys', 'SharingGroups', 'Users', 'Tags.Tags'];
foreach ($models as $model) {
$table = TableRegistry::getTableLocator()->get($model);
$statistics[$model]['amount'] = $table->find()->all()->count();
if ($table->behaviors()->has('Timestamp')) {
$query = $table->find();
$query->select([
'count' => $query->func()->count('id'),
'date' => 'DATE(modified)',
])
->where(['modified >' => new \DateTime("-{$days} days")])
->group(['date'])
->order(['date']);
$data = $query->toArray();
$interval = new \DateInterval('P1D');
$period = new \DatePeriod(new \DateTime("-{$days} days"), $interval ,new \DateTime());
$timeline = [];
foreach($period as $date){
$timeline[$date->format("Y-m-d")] = [
'time' => $date->format("Y-m-d"),
'count' => 0
];
}
foreach ($data as $entry) {
$timeline[$entry->date]['count'] = $entry->count;
}
$statistics[$model]['timeline'] = array_values($timeline);
$startCount = $table->find()->where(['modified <' => new \DateTime("-{$days} days")])->all()->count();
$endCount = $statistics[$model]['amount'];
$statistics[$model]['variation'] = $endCount - $startCount;
} else {
$statistics[$model]['timeline'] = [];
$statistics[$model]['variation'] = 0;
}
}
return $statistics;
}
public function getMigrationStatus()
{
$migrations = new Migrations();

View File

@ -979,6 +979,7 @@ class BoostrapCard extends BootstrapGeneric
'headerHTML' => '',
'footerHTML' => '',
'bodyHTML' => '',
'class' => '',
'headerClass' => '',
'bodyClass' => '',
'footerClass' => '',
@ -1010,6 +1011,7 @@ class BoostrapCard extends BootstrapGeneric
'card',
!empty($this->options['variant']) ? "bg-{$this->options['variant']}" : '',
!empty($this->options['variant']) ? $this->getTextClassForVariant($this->options['variant']) : '',
h($this->options['class']),
],
], implode('', [$this->genHeader(), $this->genBody(), $this->genFooter()]));
return $card;

View File

@ -1,3 +1,22 @@
<?php
$Parsedown = new Parsedown();
echo $Parsedown->text($md);
// $Parsedown = new Parsedown();
// echo $Parsedown->text($md);
?>
<div class="row">
<?php foreach ($statistics as $modelName => $statistics): ?>
<div class="col-sm-6 col-md-4 col-l-3 col-xl-2 mb-2">
<?php
$modelName = explode('.', $modelName);
$modelName = $modelName[count($modelName)-1];
echo $this->element('widgets/highlight-panel', [
'title' => $modelName,
'number' => $statistics['amount'],
'variation' => $statistics['variation'] ?? '',
'chartData' => $statistics['timeline'] ?? []
]);
?>
</div>
<?php endforeach ?>
</div>

View File

@ -0,0 +1,64 @@
<?php
$chartOptions = $chartOptions ?? [];
$chartData = $chartData ?? [];
$seed = mt_rand();
$chartId = "chart-{$seed}";
// Transform the chart data into the expected format
$data = [];
foreach ($chartData as $i => $entry) {
$data[] = $entry['count'];
}
?>
<div id="<?= $chartId ?>"></div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
(function() {
const passedOptions = <?= json_encode($chartOptions) ?>;
const defaultOptions = {
chart: {
id: '<?= $chartId ?>',
type: 'bar',
sparkline: {
enabled: true
},
dropShadow: {
enabled: true,
top: 1,
left: 1,
blur: 2,
opacity: 0.2,
},
animations: {
enabled: false
},
},
series: [{
data: <?= json_encode($data) ?>,
}],
colors: ['var(--success)'],
tooltip: {
x: {
show: false
},
y: {
title: {
formatter: function formatter(val) {
return '';
}
}
},
theme: '<?= !empty($darkMode) ? 'dark' : 'light' ?>'
}
}
const chartOptions = Object.assign({}, defaultOptions, passedOptions)
new ApexCharts(document.querySelector('#<?= $chartId ?>'), chartOptions).render();
// const chart = new ApexCharts(document.querySelector("#<?= $chartId ?>"), options);
// chart.render();
})()
</script>

View File

@ -0,0 +1,37 @@
<?php
$variationIcon = '';
$variationClass = '';
if ($variation == 0) {
$variationIcon = 'minus';
} elseif ($variation > 0) {
$variationIcon = 'arrow-up';
$variationClass = 'text-success';
} else {
$variationIcon = 'arrow-down';
$variationClass = 'text-danger';
}
$variationHtml = sprintf('<div class="%s"><span class="%s mr-2"></span>%s</div>',
$variationClass,
$this->FontAwesome->getClass($variationIcon),
!empty($variation) ? h($variation) : ''
);
$leftContent = sprintf('<div class="">%s</div><h2 class="my-2">%s</h2>%s',
h($title ?? ''),
h($number ?? ''),
$variationHtml
);
$rightContent = sprintf('<div class="">%s</div>', $this->element('charts/bar', [
'chartData' => $chartData
]));
$cardContent = sprintf('<div class="highlight-panel-container d-flex align-items-center justify-content-between"><div class="number-container">%s</div><div class="chart-container w-50">%s</div></div>', $leftContent, $rightContent);
echo $this->Bootstrap->card([
'variant' => 'secondary',
'bodyHTML' => $cardContent,
'bodyClass' => 'p-3'
]);
?>