diff options
| author | 2025-01-21 23:45:22 +0100 | |
|---|---|---|
| committer | 2025-01-21 23:45:22 +0100 | |
| commit | afb6f788fa9c90817c9bd21e91993f4ddb462621 (patch) | |
| tree | 0408f1f354c15aa13e09b94c2f924c43c3afbfc8 | |
| parent | f2c820dccd18eea9213a27d0401569b0f6e9a402 (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>
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 */ |
