aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar maTh <1645099+math-GH@users.noreply.github.com> 2025-01-21 23:45:22 +0100
committerGravatar GitHub <noreply@github.com> 2025-01-21 23:45:22 +0100
commitafb6f788fa9c90817c9bd21e91993f4ddb462621 (patch)
tree0408f1f354c15aa13e09b94c2f924c43c3afbfc8
parentf2c820dccd18eea9213a27d0401569b0f6e9a402 (diff)
Improve stats page layout (#7243)
* New stats box layout * repartition: table overview improved with links and icons * Show selected feed name in title * i18n string: overview * fix * fix * fix * delete unused stat in frss * Update app/i18n/fr/admin.php --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
-rw-r--r--app/i18n/cs/admin.php3
-rw-r--r--app/i18n/de/admin.php3
-rw-r--r--app/i18n/el/admin.php3
-rw-r--r--app/i18n/en-us/admin.php3
-rw-r--r--app/i18n/en/admin.php3
-rw-r--r--app/i18n/es/admin.php3
-rw-r--r--app/i18n/fa/admin.php3
-rw-r--r--app/i18n/fi/admin.php3
-rw-r--r--app/i18n/fr/admin.php3
-rw-r--r--app/i18n/he/admin.php3
-rw-r--r--app/i18n/hu/admin.php3
-rw-r--r--app/i18n/id/admin.php3
-rw-r--r--app/i18n/it/admin.php3
-rw-r--r--app/i18n/ja/admin.php3
-rw-r--r--app/i18n/ko/admin.php3
-rw-r--r--app/i18n/lv/admin.php3
-rw-r--r--app/i18n/nl/admin.php3
-rw-r--r--app/i18n/oc/admin.php3
-rw-r--r--app/i18n/pl/admin.php3
-rw-r--r--app/i18n/pt-br/admin.php3
-rw-r--r--app/i18n/ru/admin.php3
-rw-r--r--app/i18n/sk/admin.php3
-rw-r--r--app/i18n/tr/admin.php3
-rw-r--r--app/i18n/zh-cn/admin.php3
-rw-r--r--app/i18n/zh-tw/admin.php3
-rw-r--r--app/layout/aside_subscription.phtml10
-rw-r--r--app/views/stats/index.phtml146
-rw-r--r--app/views/stats/repartition.phtml132
-rw-r--r--p/themes/base-theme/frss.css77
-rw-r--r--p/themes/base-theme/frss.rtl.css77
30 files changed, 309 insertions, 208 deletions
diff --git a/app/i18n/cs/admin.php b/app/i18n/cs/admin.php
index 52eb53b71..c38ce085a 100644
--- a/app/i18n/cs/admin.php
+++ b/app/i18n/cs/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Všechny kanály',
'no_idle' => 'Nejsou žádné nečinné kanály!',
'number_entries' => '%d článků',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% ze všech',
- 'repartition' => 'Přerozdělení článků',
+ 'repartition' => 'Přerozdělení článků: %s',
'status_favorites' => 'Oblíbené',
'status_read' => 'Přečtené',
'status_total' => 'Celkem',
diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php
index 08f236ec7..deab59bdb 100644
--- a/app/i18n/de/admin.php
+++ b/app/i18n/de/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Haupt-Feeds',
'no_idle' => 'Es gibt keinen inaktiven Feed!',
'number_entries' => '%d Artikel',
+ 'overview' => 'Übersicht',
'percent_of_total' => '% Gesamt',
- 'repartition' => 'Artikel-Verteilung',
+ 'repartition' => 'Artikel-Verteilung: %s',
'status_favorites' => 'Favoriten',
'status_read' => 'Gelesen',
'status_total' => 'Gesamt',
diff --git a/app/i18n/el/admin.php b/app/i18n/el/admin.php
index c75a00dcb..40e1f5ee0 100644
--- a/app/i18n/el/admin.php
+++ b/app/i18n/el/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Κύρια ροή',
'no_idle' => 'Δεν υπάρχουν αδρανείς τροφοδοσίες!',
'number_entries' => '%d άρθρα',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% εκ του συνόλου',
- 'repartition' => 'Articles repartition', // TODO
+ 'repartition' => 'Articles repartition: %s', // TODO
'status_favorites' => 'Αγαπημένα',
'status_read' => 'Ανάγνωση',
'status_total' => 'Σύνολο',
diff --git a/app/i18n/en-us/admin.php b/app/i18n/en-us/admin.php
index 6cac9b93d..780f95543 100644
--- a/app/i18n/en-us/admin.php
+++ b/app/i18n/en-us/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Main stream', // IGNORE
'no_idle' => 'There are no idle feeds!', // IGNORE
'number_entries' => '%d articles', // IGNORE
+ 'overview' => 'Overview', // IGNORE
'percent_of_total' => '% of total', // IGNORE
- 'repartition' => 'Articles repartition', // IGNORE
+ 'repartition' => 'Articles repartition: %s', // IGNORE
'status_favorites' => 'Favorites',
'status_read' => 'Read', // IGNORE
'status_total' => 'Total', // IGNORE
diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php
index 6394d1e0a..d9df78501 100644
--- a/app/i18n/en/admin.php
+++ b/app/i18n/en/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Main stream',
'no_idle' => 'There are no idle feeds!',
'number_entries' => '%d articles',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% of total',
- 'repartition' => 'Articles repartition',
+ 'repartition' => 'Articles repartition: %s',
'status_favorites' => 'Favourites',
'status_read' => 'Read',
'status_total' => 'Total',
diff --git a/app/i18n/es/admin.php b/app/i18n/es/admin.php
index 3c2a2c76d..b34db9134 100644
--- a/app/i18n/es/admin.php
+++ b/app/i18n/es/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Salida principal',
'no_idle' => 'No hay fuentes inactivas',
'number_entries' => '%d artículos',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% del total',
- 'repartition' => 'Reparto de artículos',
+ 'repartition' => 'Reparto de artículos: %s',
'status_favorites' => 'Favoritos',
'status_read' => 'Leídos',
'status_total' => 'Total', // IGNORE
diff --git a/app/i18n/fa/admin.php b/app/i18n/fa/admin.php
index 7ad23823b..e042f031d 100644
--- a/app/i18n/fa/admin.php
+++ b/app/i18n/fa/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => ' جریان اصلی',
'no_idle' => ' هیچ فید بیکار وجود ندارد!',
'number_entries' => ' %d مقاله',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => ' درصد از کل',
- 'repartition' => ' تقسیم مجدد مقالات',
+ 'repartition' => ' تقسیم مجدد مقالات: %s', // DIRTY
'status_favorites' => ' موارد دلخواه',
'status_read' => ' بخوانید',
'status_total' => ' مجموع',
diff --git a/app/i18n/fi/admin.php b/app/i18n/fi/admin.php
index 257ee9d31..54968e980 100644
--- a/app/i18n/fi/admin.php
+++ b/app/i18n/fi/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Pääsyötevirta',
'no_idle' => 'Hiljentyneitä syötteitä ei ole.',
'number_entries' => '%d artikkelia',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% kaikista',
- 'repartition' => 'Artikkelien uudelleenjaottelu',
+ 'repartition' => 'Artikkelien uudelleenjaottelu: %s',
'status_favorites' => 'Suosikit',
'status_read' => 'Luetut',
'status_total' => 'Yhteensä',
diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php
index 12a1e14af..5fab6a178 100644
--- a/app/i18n/fr/admin.php
+++ b/app/i18n/fr/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Flux principal',
'no_idle' => 'Il n’y a aucun flux inactif !',
'number_entries' => '%d articles', // IGNORE
+ 'overview' => 'Vue d’ensemble',
'percent_of_total' => '% du total',
- 'repartition' => 'Répartition des articles',
+ 'repartition' => 'Répartition des articles: %s',
'status_favorites' => 'favoris',
'status_read' => 'lus',
'status_total' => 'total',
diff --git a/app/i18n/he/admin.php b/app/i18n/he/admin.php
index 4a9c7a9c5..017a4b57a 100644
--- a/app/i18n/he/admin.php
+++ b/app/i18n/he/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'הזנה ראשית',
'no_idle' => 'אין הזנות מובטלות!',
'number_entries' => '%d מאמרים',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% מסך הכל',
- 'repartition' => 'חלוקת המאמרים',
+ 'repartition' => 'חלוקת המאמרים: %s', // DIRTY
'status_favorites' => 'מועדפים',
'status_read' => 'נקרא',
'status_total' => 'סך הכל',
diff --git a/app/i18n/hu/admin.php b/app/i18n/hu/admin.php
index b8e4a8809..866a7a468 100644
--- a/app/i18n/hu/admin.php
+++ b/app/i18n/hu/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Minden cikk',
'no_idle' => 'Nincsenek tétlen hírforrások!',
'number_entries' => '%d cikk',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% az összesből',
- 'repartition' => 'Cikkek eloszlása',
+ 'repartition' => 'Cikkek eloszlása: %s',
'status_favorites' => 'Kedvencek',
'status_read' => 'Olvasott',
'status_total' => 'Összes',
diff --git a/app/i18n/id/admin.php b/app/i18n/id/admin.php
index 1d6f2545f..26193cd72 100644
--- a/app/i18n/id/admin.php
+++ b/app/i18n/id/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Aliran utama',
'no_idle' => 'Tidak ada idle feed!',
'number_entries' => '%d artikel',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% dari total',
- 'repartition' => 'Mengembalikan artikel',
+ 'repartition' => 'Mengembalikan artikel: %s',
'status_favorites' => 'Favorites',
'status_read' => 'Terbaca',
'status_total' => 'Total', // TODO
diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php
index 8b95a9db7..55f326c30 100644
--- a/app/i18n/it/admin.php
+++ b/app/i18n/it/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Flusso principale',
'no_idle' => 'Non ci sono feed non aggiornati',
'number_entries' => '%d articoli',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% del totale',
- 'repartition' => 'Ripartizione articoli',
+ 'repartition' => 'Ripartizione articoli: %s',
'status_favorites' => 'Preferiti',
'status_read' => 'Letti',
'status_total' => 'Totale',
diff --git a/app/i18n/ja/admin.php b/app/i18n/ja/admin.php
index a4cd2afcd..e8559f5f1 100644
--- a/app/i18n/ja/admin.php
+++ b/app/i18n/ja/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => '主なストリーム',
'no_idle' => '未使用のフィードはありません!',
'number_entries' => '%d 記事',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% 総計',
- 'repartition' => '記事の仕切り',
+ 'repartition' => '記事の仕切り: %s', // DIRTY
'status_favorites' => 'お気に入り',
'status_read' => '既読',
'status_total' => 'すべて',
diff --git a/app/i18n/ko/admin.php b/app/i18n/ko/admin.php
index dbc1d5778..c9bfd2526 100644
--- a/app/i18n/ko/admin.php
+++ b/app/i18n/ko/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => '메인 스트림',
'no_idle' => '유휴 피드가 없습니다!',
'number_entries' => '%d 개의 글',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '전체에서의 비율 (%)',
- 'repartition' => '글 분류',
+ 'repartition' => '글 분류: %s', // DIRTY
'status_favorites' => '즐겨찾기',
'status_read' => '읽음',
'status_total' => '전체',
diff --git a/app/i18n/lv/admin.php b/app/i18n/lv/admin.php
index 21bb21340..48b56d046 100644
--- a/app/i18n/lv/admin.php
+++ b/app/i18n/lv/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Galvenā plūsma',
'no_idle' => 'Nav neaktīvu barotņu!',
'number_entries' => '%d raksti',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% no kopsummas',
- 'repartition' => 'Rakstu pārdalīšana',
+ 'repartition' => 'Rakstu pārdalīšana: %s', // DIRTY
'status_favorites' => 'Mīļākie',
'status_read' => 'Izlasīti',
'status_total' => 'Kopā',
diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php
index 4f6268689..1a8c5a95a 100644
--- a/app/i18n/nl/admin.php
+++ b/app/i18n/nl/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Overzicht',
'no_idle' => 'Er is geen gepauzeerde feed!',
'number_entries' => '%d artikelen',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% van totaal',
- 'repartition' => 'Artikelverdeling',
+ 'repartition' => 'Artikelverdeling: %s',
'status_favorites' => 'Favorieten',
'status_read' => 'Gelezen',
'status_total' => 'Totaal',
diff --git a/app/i18n/oc/admin.php b/app/i18n/oc/admin.php
index e4926a2df..ea5b34767 100644
--- a/app/i18n/oc/admin.php
+++ b/app/i18n/oc/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Flux màger',
'no_idle' => 'I a pas cap d’article inactiu !',
'number_entries' => '%d articles', // IGNORE
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% del total',
- 'repartition' => 'Reparticion dels articles',
+ 'repartition' => 'Reparticion dels articles: %s',
'status_favorites' => 'Favorits',
'status_read' => 'Legit',
'status_total' => 'Total', // IGNORE
diff --git a/app/i18n/pl/admin.php b/app/i18n/pl/admin.php
index c6ee617c9..6f64ff20e 100644
--- a/app/i18n/pl/admin.php
+++ b/app/i18n/pl/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Kanał główny',
'no_idle' => 'Brak bezczynnych kanałów!',
'number_entries' => '%d wiadomości',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% wszystkich',
- 'repartition' => 'Podział wiadomości',
+ 'repartition' => 'Podział wiadomości: %s',
'status_favorites' => 'Ulubione',
'status_read' => 'Przeczytane',
'status_total' => 'Wszystkie',
diff --git a/app/i18n/pt-br/admin.php b/app/i18n/pt-br/admin.php
index 15ab3ad0d..5c5b9b0b4 100644
--- a/app/i18n/pt-br/admin.php
+++ b/app/i18n/pt-br/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Stream principal',
'no_idle' => 'Não há nenhum feed inativo!',
'number_entries' => '%d artigos',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% do total',
- 'repartition' => 'Repartição de artigos',
+ 'repartition' => 'Repartição de artigos: %s',
'status_favorites' => 'Favoritos',
'status_read' => 'Lido',
'status_total' => 'Total', // IGNORE
diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php
index fb34eb79d..b0dbc1a5d 100644
--- a/app/i18n/ru/admin.php
+++ b/app/i18n/ru/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Основной поток',
'no_idle' => 'Нет неактивных лент!',
'number_entries' => 'статей: %d',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% от всего',
- 'repartition' => 'Распределение статей',
+ 'repartition' => 'Распределение статей: %s',
'status_favorites' => 'В избранном',
'status_read' => 'Прочитано',
'status_total' => 'Всего',
diff --git a/app/i18n/sk/admin.php b/app/i18n/sk/admin.php
index 7166c2a38..d4165dc2b 100644
--- a/app/i18n/sk/admin.php
+++ b/app/i18n/sk/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Všetky kanály',
'no_idle' => 'Žiadne neaktívne kanály!',
'number_entries' => 'Počet článkov: %d',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => 'Z celkového počtu: %',
- 'repartition' => 'Rozdelenie článkov',
+ 'repartition' => 'Rozdelenie článkov: %s',
'status_favorites' => 'Obľúbené',
'status_read' => 'Prečítané',
'status_total' => 'Spolu',
diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php
index 9069f7f45..c14053a43 100644
--- a/app/i18n/tr/admin.php
+++ b/app/i18n/tr/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => 'Ana akış',
'no_idle' => 'Boşta akış yok!',
'number_entries' => '%d makale',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '% toplamın yüzdesi',
- 'repartition' => 'Makale dağılımı',
+ 'repartition' => 'Makale dağılımı: %s',
'status_favorites' => 'Favoriler',
'status_read' => 'Okunmuş',
'status_total' => 'Toplam',
diff --git a/app/i18n/zh-cn/admin.php b/app/i18n/zh-cn/admin.php
index 251c0a97a..4c107d2bb 100644
--- a/app/i18n/zh-cn/admin.php
+++ b/app/i18n/zh-cn/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => '首页',
'no_idle' => '订阅源近期皆有更新!',
'number_entries' => '%d 篇文章',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '%',
- 'repartition' => '文章分布',
+ 'repartition' => '文章分布: %s', // DIRTY
'status_favorites' => '收藏',
'status_read' => '已读',
'status_total' => '总计',
diff --git a/app/i18n/zh-tw/admin.php b/app/i18n/zh-tw/admin.php
index 6f63f0458..65b2deea7 100644
--- a/app/i18n/zh-tw/admin.php
+++ b/app/i18n/zh-tw/admin.php
@@ -148,8 +148,9 @@ return array(
'main_stream' => '首頁',
'no_idle' => '訂閱源近期皆有更新!',
'number_entries' => '%d 篇文章',
+ 'overview' => 'Overview', // TODO
'percent_of_total' => '%',
- 'repartition' => '文章分布',
+ 'repartition' => '文章分布: %s', // DIRTY
'status_favorites' => '收藏',
'status_read' => '已讀',
'status_total' => '總計',
diff --git a/app/layout/aside_subscription.phtml b/app/layout/aside_subscription.phtml
index 61b0ee38e..ce17eaa26 100644
--- a/app/layout/aside_subscription.phtml
+++ b/app/layout/aside_subscription.phtml
@@ -52,7 +52,9 @@
</li>
</ul>
</nav>
-<a class="close-aside" href="#close">❌</a>
-<nav class="nav_menu nav_mobile">
- <a class="btn toggle_aside" href="#aside_feed"><?= _i('category') ?></a>
-</nav>
+<?php if (Minz_Request::actionName() != 'repartition') { ?>
+ <a class="close-aside" href="#close">❌</a>
+ <nav class="nav_menu nav_mobile">
+ <a class="btn toggle_aside" href="#aside_feed"><?= _i('category') ?></a>
+ </nav>
+<?php } ?>
diff --git a/app/views/stats/index.phtml b/app/views/stats/index.phtml
index f3fc3e986..88c4f0a3c 100644
--- a/app/views/stats/index.phtml
+++ b/app/views/stats/index.phtml
@@ -6,77 +6,77 @@
<main class="post">
<h1><?= _t('admin.stats.main') ?></h1>
- <div class="stat-grid">
- <div class="stat half">
- <h2><?= _t('admin.stats.entry_repartition') ?></h2>
- <div class="table-wrapper scrollbar-thin">
- <table>
- <thead>
- <tr>
- <th> </th>
- <th><?= _t('admin.stats.main_stream') ?></th>
- <th><?= _t('admin.stats.all_feeds') ?></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <th><?= _t('admin.stats.status_total') ?></th>
- <td class="numeric"><?= format_number($this->repartitions['main_stream']['total'] ?? -1) ?></td>
- <td class="numeric"><?= format_number($this->repartitions['all_feeds']['total'] ?? -1) ?></td>
- </tr>
- <tr>
- <th><?= _t('admin.stats.status_read') ?></th>
- <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_reads'] ?? -1) ?></td>
- <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_reads'] ?? -1) ?></td>
- </tr>
- <tr>
- <th><?= _t('admin.stats.status_unread') ?></th>
- <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_unreads'] ?? -1) ?></td>
- <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_unreads'] ?? -1) ?></td>
- </tr>
- <tr>
- <th><?= _t('admin.stats.status_favorites') ?></th>
- <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_favorites'] ?? -1) ?></td>
- <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_favorites'] ?? -1) ?></td>
- </tr>
- </tbody>
- </table>
- </div>
+ <div class="box">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_repartition') ?></h2></div>
+ <div class="box-content scrollbar-thin">
+ <table>
+ <thead>
+ <tr>
+ <th> </th>
+ <th><?= _t('admin.stats.main_stream') ?></th>
+ <th><?= _t('admin.stats.all_feeds') ?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th><?= _t('admin.stats.status_total') ?></th>
+ <td class="numeric"><?= format_number($this->repartitions['main_stream']['total'] ?? -1) ?></td>
+ <td class="numeric"><?= format_number($this->repartitions['all_feeds']['total'] ?? -1) ?></td>
+ </tr>
+ <tr>
+ <th><?= _t('admin.stats.status_read') ?></th>
+ <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_reads'] ?? -1) ?></td>
+ <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_reads'] ?? -1) ?></td>
+ </tr>
+ <tr>
+ <th><?= _t('admin.stats.status_unread') ?></th>
+ <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_unreads'] ?? -1) ?></td>
+ <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_unreads'] ?? -1) ?></td>
+ </tr>
+ <tr>
+ <th><?= _t('admin.stats.status_favorites') ?></th>
+ <td class="numeric"><?= format_number($this->repartitions['main_stream']['count_favorites'] ?? -1) ?></td>
+ <td class="numeric"><?= format_number($this->repartitions['all_feeds']['count_favorites'] ?? -1) ?></td>
+ </tr>
+ </tbody>
+ </table>
</div>
+ </div>
+
- <div class="stat half">
- <h2><?= _t('admin.stats.top_feed') ?></h2>
- <div class="table-wrapper scrollbar-thin">
- <table>
- <thead>
+ <div class="box double-height">
+ <div class="box-title"><h2><?= _t('admin.stats.top_feed') ?></h2></div>
+ <div class="box-content scrollbar-thin">
+ <table>
+ <thead>
+ <tr>
+ <th><?= _t('admin.stats.feed') ?></th>
+ <th><?= _t('admin.stats.category') ?></th>
+ <th><?= _t('admin.stats.entry_count') ?></th>
+ <th><?= _t('admin.stats.percent_of_total') ?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php foreach ($this->topFeed as $feed): ?>
<tr>
- <th><?= _t('admin.stats.feed') ?></th>
- <th><?= _t('admin.stats.category') ?></th>
- <th><?= _t('admin.stats.entry_count') ?></th>
- <th><?= _t('admin.stats.percent_of_total') ?></th>
+ <td><a href="<?= _url('stats', 'repartition', 'id', $feed['id']) ?>"><?= $feed['name'] ?></a></td>
+ <td><?= $feed['category'] ?></td>
+ <td class="numeric"><?= format_number($feed['count']) ?></td>
+ <td class="numeric"><?php
+ if (!empty($this->repartitions['all_feeds']['total'])) {
+ echo format_number($feed['count'] / $this->repartitions['all_feeds']['total'] * 100, 1);
+ }
+ ?></td>
</tr>
- </thead>
- <tbody>
- <?php foreach ($this->topFeed as $feed): ?>
- <tr>
- <td><a href="<?= _url('stats', 'repartition', 'id', $feed['id']) ?>"><?= $feed['name'] ?></a></td>
- <td><?= $feed['category'] ?></td>
- <td class="numeric"><?= format_number($feed['count']) ?></td>
- <td class="numeric"><?php
- if (!empty($this->repartitions['all_feeds']['total'])) {
- echo format_number($feed['count'] / $this->repartitions['all_feeds']['total'] * 100, 1);
- }
- ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- </div>
+ <?php endforeach; ?>
+ </tbody>
+ </table>
</div>
-
- <div class="stat">
- <h2><?= _t('admin.stats.entry_per_day') ?></h2>
- <div>
+ </div>
+ <br />
+ <div class="box double-width double-height">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_per_day') ?></h2></div>
+ <div class="box-content scrollbar-thin">
<canvas id="statsEntriesPerDay"></canvas>
<script class="jsonData-stats" type="application/json">
<?= json_encode([
@@ -140,10 +140,10 @@ $entryLabels = array_keys($entryData);
$entryColors = array_map(fn($label) => $colorMap[$label], $entryLabels);
$entryValues = array_values($entryData);
?>
-
- <div class="stat half">
- <h2><?= _t('admin.stats.feed_per_category') ?></h2>
- <div>
+<br id="stats_per_category" />
+ <div class="box double-height" id="feed_per_category">
+ <div class="box-title"><h2><?= _t('admin.stats.feed_per_category') ?></h2><a href="#feed_per_category" class="btn target-hidden">+</a><a href="#stats_per_category" class="btn target-visible">-</a></div>
+ <div class="box-content scrollbar-thin">
<canvas id="statsFeedsPerCategory"></canvas>
<script class="jsonData-stats" type="application/json">
<?= json_encode([
@@ -157,9 +157,9 @@ $entryValues = array_values($entryData);
</div>
</div>
- <div class="stat half">
- <h2><?= _t('admin.stats.entry_per_category') ?></h2>
- <div>
+ <div class="box double-height" id="entry_per_category">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_per_category') ?></h2><a href="#entry_per_category" class="btn target-hidden">+</a><a href="#stats_per_category" class="btn target-visible">-</a></div>
+ <div class="box-content scrollbar-thin">
<canvas id="statsEntriesPerCategory"></canvas>
<script class="jsonData-stats" type="application/json">
<?= json_encode([
diff --git a/app/views/stats/repartition.phtml b/app/views/stats/repartition.phtml
index e212e79bf..59cae9e1a 100644
--- a/app/views/stats/repartition.phtml
+++ b/app/views/stats/repartition.phtml
@@ -2,9 +2,11 @@
declare(strict_types=1);
/** @var FreshRSS_ViewStats $this */
$this->partial('aside_subscription');
+ $feedname = _t('admin.stats.all_feeds');
?>
-<main class="post ">
- <h1><?= _t('admin.stats.repartition') ?></h1>
+
+<nav class="nav_menu">
+ <a class="btn toggle_aside" href="#aside_feed"><?= _i('category') ?></a>
<select id="feed_select" class="select-change">
<option data-url="<?= _url('stats', 'repartition') ?>"><?= _t('admin.stats.all_feeds') ?></option>
@@ -16,6 +18,7 @@
if ($this->feed !== null && $feed->id() == $this->feed->id()) {
echo '<option value="', $feed->id(), '" selected="selected" data-url="',
_url('stats', 'repartition', 'id', $feed->id()), '">', $feed->name(), '</option>';
+ $feedname = $feed->name();
} else {
echo '<option value="', $feed->id(), '" data-url="',
_url('stats', 'repartition', 'id', $feed->id()), '">', $feed->name(), '</option>';
@@ -31,74 +34,91 @@
<?= _i('configure') ?> <?= _t('gen.action.manage') ?>
</a>
<?php }?>
+</nav>
+
+<main class="post">
+ <h1><?= _t('admin.stats.repartition', $feedname) ?></h1>
- <div class="stat-grid">
- <div class="stat table-wrapper scrollbar-thin">
+ <div class="box double-width">
+ <div class="box-title"><h2><?= _t('admin.stats.overview') ?></h2></div>
+ <div class="box-content scrollbar-thin">
<table>
<tr>
<th><?= _t('admin.stats.status_total') ?></th>
- <th><?= _t('admin.stats.status_read') ?></th>
- <th><?= _t('admin.stats.status_unread') ?></th>
- <th><?= _t('admin.stats.status_favorites') ?></th>
+ <th><?= _i('read') ?> <?= _t('admin.stats.status_read') ?></th>
+ <th><?= _i('unread') ?> <?= _t('admin.stats.status_unread') ?></th>
+ <th><?= _i('starred') ?> <?= _t('admin.stats.status_favorites') ?></th>
</tr>
<tr>
- <td class="numeric"><?= $this->repartition['total'] ?? -1 ?></td>
- <td class="numeric"><?= $this->repartition['count_reads'] ?? -1 ?></td>
- <td class="numeric"><?= $this->repartition['count_unreads'] ?? -1 ?></td>
- <td class="numeric"><?= $this->repartition['count_favorites'] ?? -1 ?></td>
+ <?php
+ $feedID = $this->feed !== null ? $this->feed->id() : 0;
+ if ($feedID === 0) { ?>
+ <td class="numeric"><?= $this->repartition['total'] ?? -1 ?></td>
+ <td class="numeric"><?= $this->repartition['count_reads'] ?? -1 ?></td>
+ <td class="numeric"><?= $this->repartition['count_unreads'] ?? -1 ?></td>
+ <td class="numeric"><a href="<?= _url('index', 'index', 'get', 's') ?>" title="<?= _t('gen.action.filter') ?>"><?= $this->repartition['count_favorites'] ?? -1 ?></a></td>
+ <?php
+ } else {
+ ?>
+ <td class="numeric"><a href="<?= _url('index', 'index', 'get', 'f_' . $feedID, 'state', FreshRSS_Entry::STATE_ALL) ?>" title="<?= _t('gen.action.filter') ?>"><?= $this->repartition['total'] ?? -1 ?></a></td>
+ <td class="numeric"><a href="<?= _url('index', 'index', 'get', 'f_' . $feedID, 'state', FreshRSS_Entry::STATE_READ) ?>" title="<?= _t('gen.action.filter') ?>"><?= $this->repartition['count_reads'] ?? -1 ?></a></td>
+ <td class="numeric"><a href="<?= _url('index', 'index', 'get', 'f_' . $feedID, 'state', FreshRSS_Entry::STATE_NOT_READ) ?>" title="<?= _t('gen.action.filter') ?>"><?= $this->repartition['count_unreads'] ?? -1 ?></a></td>
+ <td class="numeric"><a href="<?= _url('index', 'index', 'get', 'f_' . $feedID, 'state', FreshRSS_Entry::STATE_FAVORITE) ?>" title="<?= _t('gen.action.filter') ?>"><?= $this->repartition['count_favorites'] ?? -1 ?></a></td>
+ <?php } ?>
</tr>
</table>
</div>
+ </div>
- <div class="stat">
- <h2><?= _t('admin.stats.entry_per_hour', $this->averageHour) ?></h2>
- <div>
- <canvas id="statsEntriesPerHour"></canvas>
- <script class="jsonData-stats" type="application/json">
- <?php
- echo json_encode([
- 'canvasID' => 'statsEntriesPerHour',
- 'charttype' => 'bar',
- 'data' => $this->repartitionHour,
- 'label' => _t('admin.stats.entry_count'),
- 'xAxisLabels' => $this->hours24Labels
- ], JSON_UNESCAPED_UNICODE);
- ?></script>
- </div>
+ <div class="box double-width double-height">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_per_hour', $this->averageHour) ?></h2></div>
+ <div class="box-content scrollbar-thin">
+ <canvas id="statsEntriesPerHour"></canvas>
+ <script class="jsonData-stats" type="application/json">
+ <?php
+ echo json_encode([
+ 'canvasID' => 'statsEntriesPerHour',
+ 'charttype' => 'bar',
+ 'data' => $this->repartitionHour,
+ 'label' => _t('admin.stats.entry_count'),
+ 'xAxisLabels' => $this->hours24Labels
+ ], JSON_UNESCAPED_UNICODE);
+ ?></script>
</div>
+ </div>
- <div class="stat half">
- <h2><?= _t('admin.stats.entry_per_day_of_week', $this->averageDayOfWeek) ?></h2>
- <div>
- <canvas id="statsEntriesPerDayOfWeek"></canvas>
- <script class="jsonData-stats" type="application/json">
- <?php
- echo json_encode([
- 'canvasID' => 'statsEntriesPerDayOfWeek',
- 'charttype' => 'bar',
- 'data' => $this->repartitionDayOfWeek,
- 'label' => _t('admin.stats.entry_count'),
- 'xAxisLabels' => $this->days,
- ], JSON_UNESCAPED_UNICODE);
- ?></script>
- </div>
+ <br />
+ <div class="box">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_per_day_of_week', $this->averageDayOfWeek) ?></h2></div>
+ <div class="box-content scrollbar-thin">
+ <canvas id="statsEntriesPerDayOfWeek"></canvas>
+ <script class="jsonData-stats" type="application/json">
+ <?php
+ echo json_encode([
+ 'canvasID' => 'statsEntriesPerDayOfWeek',
+ 'charttype' => 'bar',
+ 'data' => $this->repartitionDayOfWeek,
+ 'label' => _t('admin.stats.entry_count'),
+ 'xAxisLabels' => $this->days,
+ ], JSON_UNESCAPED_UNICODE);
+ ?></script>
</div>
+ </div>
- <div class="stat half">
- <h2><?= _t('admin.stats.entry_per_month', $this->averageMonth) ?></h2>
- <div>
- <canvas id="statsEntriesPerMonth"></canvas>
- <script class="jsonData-stats" type="application/json">
- <?php
- echo json_encode([
- 'canvasID' => 'statsEntriesPerMonth',
- 'charttype' => 'bar',
- 'data' => $this->repartitionMonth,
- 'label' => _t('admin.stats.entry_count'),
- 'xAxisLabels' => $this->months,
- ], JSON_UNESCAPED_UNICODE);
- ?></script>
- </div>
+ <div class="box">
+ <div class="box-title"><h2><?= _t('admin.stats.entry_per_month', $this->averageMonth) ?></h2></div>
+ <div class="box-content scrollbar-thin">
+ <canvas id="statsEntriesPerMonth"></canvas>
+ <script class="jsonData-stats" type="application/json">
+ <?php
+ echo json_encode([
+ 'canvasID' => 'statsEntriesPerMonth',
+ 'charttype' => 'bar',
+ 'data' => $this->repartitionMonth,
+ 'label' => _t('admin.stats.entry_count'),
+ 'xAxisLabels' => $this->months,
+ ], JSON_UNESCAPED_UNICODE);
+ ?></script>
</div>
</div>
</main>
diff --git a/p/themes/base-theme/frss.css b/p/themes/base-theme/frss.css
index 09ccd129b..bc5e8a9a1 100644
--- a/p/themes/base-theme/frss.css
+++ b/p/themes/base-theme/frss.css
@@ -933,13 +933,34 @@ input[type="checkbox"]:focus-visible {
/*=== Boxes */
.box {
- margin: 20px 20px 20px 0;
+ margin: 1.25rem 1.25rem 1.25rem 0;
display: inline-block;
max-width: 95%;
width: 30rem;
vertical-align: top;
}
+.box.double-width,
+.box:target {
+ width: 61.25rem;
+}
+
+.box .target-hidden {
+ display: initial;
+}
+
+.box:target .target-hidden {
+ display: none;
+}
+
+.box .target-visible {
+ display: none;
+}
+
+.box:target .target-visible {
+ display: initial;
+}
+
.box.visible-semi {
border-style: dashed;
opacity: 0.5;
@@ -972,6 +993,18 @@ input[type="checkbox"]:focus-visible {
overflow: auto;
}
+.box .box-content table {
+ width: calc(100% - 1.25rem);
+}
+
+.box.double-height .box-content {
+ max-height: 520px;
+}
+
+.box:target .box-content {
+ max-height: fit-content;
+}
+
.box .box-content .feed.item {
font-size: 0.9rem;
line-height: 1.5;
@@ -1865,26 +1898,13 @@ a.website:hover .favicon {
}
/*=== Statistiques */
-.stat-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-gap: 20px;
-}
-
-.stat {
- grid-column: 1 / span 2;
-}
-
-.stat.half {
- grid-column: auto;
-}
-
-.stat > table {
- width: 100%;
-}
-
-.statGraph {
- height: 300px;
+.box .box-title .btn {
+ position: absolute;
+ right: 1rem;
+ line-height: 1;
+ min-height: 1rem;
+ padding: 0.25rem;
+ text-align: center;
}
/*=== GLOBAL VIEW */
@@ -2292,10 +2312,21 @@ html.slider-active {
.nav_menu {
padding-top: var(--frss-padding-top-bottom);
padding-bottom: var(--frss-padding-top-bottom);
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
background: inherit;
text-align: center;
}
+.nav_menu .stick {
+ max-width: 500px;
+}
+
+.nav_menu select {
+ max-width: 300px;
+ width: 60%;
+}
+
.nav_mobile {
display: none;
}
@@ -2692,10 +2723,6 @@ html.slider-active {
#slider.active:target + #close-slider {
display: none;
}
-
- .stat.half {
- grid-column: 1 / span 2;
- }
}
/*=== PRINTER */
diff --git a/p/themes/base-theme/frss.rtl.css b/p/themes/base-theme/frss.rtl.css
index fcb0ce05d..8f90de8b7 100644
--- a/p/themes/base-theme/frss.rtl.css
+++ b/p/themes/base-theme/frss.rtl.css
@@ -933,13 +933,34 @@ input[type="checkbox"]:focus-visible {
/*=== Boxes */
.box {
- margin: 20px 0 20px 20px;
+ margin: 1.25rem 0 1.25rem 1.25rem;
display: inline-block;
max-width: 95%;
width: 30rem;
vertical-align: top;
}
+.box.double-width,
+.box:target {
+ width: 61.25rem;
+}
+
+.box .target-hidden {
+ display: initial;
+}
+
+.box:target .target-hidden {
+ display: none;
+}
+
+.box .target-visible {
+ display: none;
+}
+
+.box:target .target-visible {
+ display: initial;
+}
+
.box.visible-semi {
border-style: dashed;
opacity: 0.5;
@@ -972,6 +993,18 @@ input[type="checkbox"]:focus-visible {
overflow: auto;
}
+.box .box-content table {
+ width: calc(100% - 1.25rem);
+}
+
+.box.double-height .box-content {
+ max-height: 520px;
+}
+
+.box:target .box-content {
+ max-height: fit-content;
+}
+
.box .box-content .feed.item {
font-size: 0.9rem;
line-height: 1.5;
@@ -1865,26 +1898,13 @@ a.website:hover .favicon {
}
/*=== Statistiques */
-.stat-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-gap: 20px;
-}
-
-.stat {
- grid-column: 1 / span 2;
-}
-
-.stat.half {
- grid-column: auto;
-}
-
-.stat > table {
- width: 100%;
-}
-
-.statGraph {
- height: 300px;
+.box .box-title .btn {
+ position: absolute;
+ left: 1rem;
+ line-height: 1;
+ min-height: 1rem;
+ padding: 0.25rem;
+ text-align: center;
}
/*=== GLOBAL VIEW */
@@ -2292,10 +2312,21 @@ html.slider-active {
.nav_menu {
padding-top: var(--frss-padding-top-bottom);
padding-bottom: var(--frss-padding-top-bottom);
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
background: inherit;
text-align: center;
}
+.nav_menu .stick {
+ max-width: 500px;
+}
+
+.nav_menu select {
+ max-width: 300px;
+ width: 60%;
+}
+
.nav_mobile {
display: none;
}
@@ -2692,10 +2723,6 @@ html.slider-active {
#slider.active:target + #close-slider {
display: none;
}
-
- .stat.half {
- grid-column: 1 / span 2;
- }
}
/*=== PRINTER */