mirror of
https://github.com/Lissy93/dashy.git
synced 2026-06-06 08:44:23 -04:00
✨ Adds debug view, removes about page
This commit is contained in:
1
src/assets/interface-icons/config-debug-menu.svg
Normal file
1
src/assets/interface-icons/config-debug-menu.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path fill="currentColor" d="M224 160C224 107 267 64 320 64C373 64 416 107 416 160L416 163.6C416 179.3 403.3 192 387.6 192L252.5 192C236.8 192 224.1 179.3 224.1 163.6L224.1 160zM569.6 172.8C580.2 186.9 577.3 207 563.2 217.6L465.4 290.9C470.7 299.8 474.7 309.6 477.2 320L576 320C593.7 320 608 334.3 608 352C608 369.7 593.7 384 576 384L480 384L480 416C480 418.6 479.9 421.3 479.8 423.9L563.2 486.4C577.3 497 580.2 517.1 569.6 531.2C559 545.3 538.9 548.2 524.8 537.6L461.7 490.3C438.5 534.5 395.2 566.5 344 574.2L344 344C344 330.7 333.3 320 320 320C306.7 320 296 330.7 296 344L296 574.2C244.8 566.5 201.5 534.5 178.3 490.3L115.2 537.6C101.1 548.2 81 545.3 70.4 531.2C59.8 517.1 62.7 497 76.8 486.4L160.2 423.9C160.1 421.3 160 418.7 160 416L160 384L64 384C46.3 384 32 369.7 32 352C32 334.3 46.3 320 64 320L162.8 320C165.3 309.6 169.3 299.8 174.6 290.9L76.8 217.6C62.7 207 59.8 186.9 70.4 172.8C81 158.7 101.1 155.8 115.2 166.4L224 248C236.3 242.9 249.8 240 264 240L376 240C390.2 240 403.7 242.8 416 248L524.8 166.4C538.9 155.8 559 158.7 569.6 172.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "App Info",
|
||||
"error-log": "Fehlerprotokoll",
|
||||
"no-errors": "Keine kürzlichen Fehler erkannt",
|
||||
"help-support": "Hilfe & Support",
|
||||
"help-support-description": "Um beim Betrieb oder der Konfiguration von Dashy Hilfe zu bekommen, siehe die",
|
||||
"help-support-discussions": "Diskussionen",
|
||||
"support-dashy": "Dashy unterstützen",
|
||||
"support-dashy-description": "Für Wege, sich zu beteiligen, besuchen Sie die",
|
||||
"support-dashy-link": "Contributions Seite",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Πληροφορίες Εφαρμογής",
|
||||
"error-log": "Αρχείο Καταγραφής Σφαλμάτων",
|
||||
"no-errors": "Δεν εντοπίστηκαν πρόσφατα σφάλματα",
|
||||
"help-support": "Βοήθεια & Υποστήριξη",
|
||||
"help-support-description": "Για να λάβετε υποστήριξη σχετικά με την εκτέλεση ή με τη διαμόρφωση του Dashy, ανατρέξτε στις",
|
||||
"help-support-discussions": "Συζητήσεις",
|
||||
"support-dashy": "Υποστήριξη του Dashy",
|
||||
"support-dashy-description": "Για τρόπους με τους οποίους μπορείτε να συνεισφέρετε, ανατρέξτε στη",
|
||||
"support-dashy-link": "Σελίδα συνεισφορών",
|
||||
|
||||
@@ -50,16 +50,15 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "App Info",
|
||||
"error-log": "Error Log",
|
||||
"no-errors": "No recent errors detected",
|
||||
"help-support": "Help & Support",
|
||||
"help-support-description": "For getting support with running or configuring Dashy, see the",
|
||||
"help-support-discussions": "Discussions",
|
||||
"support-dashy": "Supporting Dashy",
|
||||
"support-dashy-description": "For ways that you can get involved, check out the",
|
||||
"support-dashy-link": "Contributions page",
|
||||
"sponsor-heading": "Sponsor Dashy",
|
||||
"sponsor-l1-prefix": "Enjoying Dashy? Consider",
|
||||
"sponsor-l1-link": "sponsoring me on GitHub",
|
||||
"sponsor-l1-suffix": "to help fund ongoing development 🩷",
|
||||
"report-bug": "Report a Bug",
|
||||
"report-bug-description": "If you think you've found a bug, then please",
|
||||
"report-bug-description": "If you think you've found a bug, then",
|
||||
"report-bug-debug-link": "check the debug menu",
|
||||
"report-bug-middle": "and",
|
||||
"report-bug-link": "raise an Issue",
|
||||
"more-info": "More Info",
|
||||
"source": "Source",
|
||||
@@ -81,7 +80,7 @@
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Main Menu",
|
||||
"view-config-tab": "View Config",
|
||||
"view-config-tab": "Export Config",
|
||||
"edit-config-tab": "Edit Config",
|
||||
"custom-css-tab": "Custom Styles",
|
||||
"heading": "Configuration Options",
|
||||
@@ -95,7 +94,8 @@
|
||||
"reset-settings-button": "Reset Local Settings",
|
||||
"disabled-note": "Some configuration features have been disabled by your administrator",
|
||||
"small-screen-note": "You are using a very small screen, and some screens in this menu may not be optimal",
|
||||
"app-info-button": "App Info",
|
||||
"app-info-button": "About",
|
||||
"debug-info-button": "Debug Info",
|
||||
"backup-note": "It is recommended to make a backup of your configuration before making changes.",
|
||||
"reset-config-msg-l1": "This will remove all user settings from local storage, but won't affect your 'conf.yml' file.",
|
||||
"reset-config-msg-l2": "You should first backup any changes you've made locally, if you want to use them in the future.",
|
||||
@@ -153,6 +153,68 @@
|
||||
"sw-update-available": "A new version of Dashy is available.",
|
||||
"sw-update-action": "Refresh"
|
||||
},
|
||||
"debug": {
|
||||
"getting-help": "Getting Help",
|
||||
"getting-help-msg": "If you've hit a snag, the community can help.",
|
||||
"resources": {
|
||||
"troubleshooting-name": "Troubleshooting",
|
||||
"troubleshooting-desc": "We've outlined fixes for common issues here",
|
||||
"docs-name": "Documentation",
|
||||
"docs-desc": "Usage guides and configuring instructions",
|
||||
"source-name": "Source code",
|
||||
"source-desc": "Otherwise, you can determine the issue from the code",
|
||||
"email-name": "Email Support",
|
||||
"email-note": "(sponsors only)",
|
||||
"email-desc": "Drop me a line, and I will try and help"
|
||||
},
|
||||
"reporting-bug": "Reporting a Bug",
|
||||
"reporting-bug-l1-prefix": "If you've found something not working as intended, please",
|
||||
"reporting-bug-l1-link": "open an issue",
|
||||
"reporting-bug-l1-suffix": "on our GitHub repo.",
|
||||
"reporting-bug-l2-intro": "When raising a bug report, please include the relevant info, such as:",
|
||||
"reporting-bug-list": {
|
||||
"version": "Dashy version",
|
||||
"deployment": "Deployment type",
|
||||
"errors": "Error logs",
|
||||
"config": "Config snippets",
|
||||
"overrides": "Relevant overrides",
|
||||
"environment": "Environment info"
|
||||
},
|
||||
"reporting-bug-note": "Be sure to redact any sensitive info. Tickets which don't include enough information to debug, diagnose and fix may be closed. Due to time limitations, support and feature requests from sponsors are prioritized.",
|
||||
"app-version": "App Version",
|
||||
"error-log": "Error Log",
|
||||
"error-log-hint-prefix": "See",
|
||||
"error-log-hint-link": "here",
|
||||
"error-log-hint-suffix": "for instructions on how to view the browser logs. There may also be useful info in the server logs.",
|
||||
"no-errors": "No errors recorded this session.",
|
||||
"current-config": "Current Config",
|
||||
"current-config-hint": "When opening an issue, please include the relevant parts of your config file.",
|
||||
"config-render-error": "Could not render config: {error}",
|
||||
"local-storage": "Local Storage",
|
||||
"local-storage-hint": "Settings saved in this browser. These override defaults until cleared.",
|
||||
"no-local-storage": "Nothing stored locally.",
|
||||
"local-storage-error": "Could not read local storage: {error}",
|
||||
"environment": "Environment",
|
||||
"environment-hint": "Browser and device info to include when filing a bug report.",
|
||||
"env": {
|
||||
"unknown": "Unknown",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"browser": "Browser",
|
||||
"os": "Operating System",
|
||||
"viewport": "Viewport",
|
||||
"screen": "Screen",
|
||||
"dpr": "Pixel Ratio",
|
||||
"languages": "Languages",
|
||||
"timezone": "Timezone",
|
||||
"colorScheme": "Color Scheme",
|
||||
"reducedMotion": "Reduced Motion",
|
||||
"online": "Online",
|
||||
"route": "Current Route",
|
||||
"mode": "Build Mode",
|
||||
"swActive": "Service Worker"
|
||||
}
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Change Application Language",
|
||||
"dropdown-label": "Select a Language",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Informations sur l'application",
|
||||
"error-log": "Journal des erreurs",
|
||||
"no-errors": "Aucune erreur récente détectée",
|
||||
"help-support": "Aide & Support",
|
||||
"help-support-description": "Pour obtenir de l'aide pour faire tourner ou configurer Dashy, voir les",
|
||||
"help-support-discussions": "discussions",
|
||||
"support-dashy": "Soutenir Dashy",
|
||||
"support-dashy-description": "Pour savoir comment vous pouvez vous impliquer, consultez la page",
|
||||
"support-dashy-link": "« Contributions »",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Información da aplicación",
|
||||
"error-log": "Rexistro de erros",
|
||||
"no-errors": "Non se detectaron erros recentes",
|
||||
"help-support": "Axuda e soporte",
|
||||
"help-support-description": "Para obter axuda sobre a execución ou configuración de Dashy, consulta as",
|
||||
"help-support-discussions": "Discusións",
|
||||
"support-dashy": "Apoia Dashy",
|
||||
"support-dashy-description": "Para saber como participar, consulta a páxina de",
|
||||
"support-dashy-link": "Contribucións",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "App Info",
|
||||
"error-log": "Hibanapló",
|
||||
"no-errors": "Nem található friss hiba",
|
||||
"help-support": "Súgó és támogatás",
|
||||
"help-support-description": "Ha segítségre van szükséged a Dashy futtatásához vagy beállításához, nézd meg a",
|
||||
"help-support-discussions": "fórumot",
|
||||
"support-dashy": "Dashy támogatása",
|
||||
"support-dashy-description": "Ha szeretnél részt venni a projektben, nézd meg a",
|
||||
"support-dashy-link": "közreműködők oldalát",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "アプリ情報",
|
||||
"error-log": "エラーログ",
|
||||
"no-errors": "エラーはありません",
|
||||
"help-support": "ヘルプとサポート",
|
||||
"help-support-description": "Dashyの実行や設定についてサポートが必要な場合は、こちらをご覧ください: ",
|
||||
"help-support-discussions": "Discussions",
|
||||
"support-dashy": "Dashyを支援",
|
||||
"support-dashy-description": "参加する方法を知るには、こちらをご覧ください: ",
|
||||
"support-dashy-link": "コントリビューションページ",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Тиркеме жөнүндө маалымат",
|
||||
"error-log": "Каталар журналы",
|
||||
"no-errors": "Жакында каталар аныкталган жок",
|
||||
"help-support": "Жардам жана колдоо",
|
||||
"help-support-description": "Dashy'ди иштетүү же конфигурациялоо боюнча жардам алуу үчүн төмөнкүгө кайрылыңыз",
|
||||
"help-support-discussions": "Талкуулар",
|
||||
"support-dashy": "Dashy'ди колдоо",
|
||||
"support-dashy-description": "Катышуунун жолдору жөнүндө маалымат алуу үчүн",
|
||||
"support-dashy-link": "Салым кошкондор бети",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Informații Aplicație",
|
||||
"error-log": "Jurnal Erori",
|
||||
"no-errors": "Nicio eroare recentă detectată",
|
||||
"help-support": "Ajutor & Suport",
|
||||
"help-support-description": "Pentru suport în utilizarea sau configurarea Dashy, consultați",
|
||||
"help-support-discussions": "Discuțiile",
|
||||
"support-dashy": "Suport pentru Dashy",
|
||||
"support-dashy-description": "Pentru moduri în care poți contribui, verificați",
|
||||
"support-dashy-link": "Pagina de Contribuții",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Информация о Приложении",
|
||||
"error-log": "Журнал Ошибок",
|
||||
"no-errors": "Ошибок не зафиксировано",
|
||||
"help-support": "Помощь и Поддержка",
|
||||
"help-support-description": "Для получения поддержки в запуске и настройке Dashy, обратитесь за помощью на",
|
||||
"help-support-discussions": "страницу Discussions",
|
||||
"support-dashy": "Поддержать Dashy",
|
||||
"support-dashy-description": "Если вы хотите поддержать проект, пожалуйста посетите страницу",
|
||||
"support-dashy-link": "Contributions",
|
||||
|
||||
@@ -47,11 +47,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Uygulama Bilgisi",
|
||||
"error-log": "Hata Günlüğü",
|
||||
"no-errors": "Son zamanlarda hata tespit edilmedi",
|
||||
"help-support": "Yardım ve Destek",
|
||||
"help-support-description": "Dashy'nin çalıştırılması veya yapılandırılması konusunda destek almak için şuraya bakın:",
|
||||
"help-support-discussions": "Tartışmalar",
|
||||
"support-dashy": "Dashy'yi Destekleyin",
|
||||
"support-dashy-description": "Katkıda bulunabileceğiniz yollar için şuraya göz atın:",
|
||||
"support-dashy-link": "Katkı sayfası",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Інформація про програму",
|
||||
"error-log": "Журнал помилок",
|
||||
"no-errors": "Останніх помилок не виявлено",
|
||||
"help-support": "Допомога та підтримка",
|
||||
"help-support-description": "Щоб отримати підтримку щодо запуску чи налаштування Dashy, див.",
|
||||
"help-support-discussions": "Обговорення",
|
||||
"support-dashy": "Підтримка Dashy",
|
||||
"support-dashy-description": "Щоб дізнатися, як ви можете взяти участь, перегляньте",
|
||||
"support-dashy-link": "Сторінка внесків",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "应用信息",
|
||||
"error-log": "错误日志",
|
||||
"no-errors": "未检测到最近的错误",
|
||||
"help-support": "帮助与支持",
|
||||
"help-support-description": "如需有关Dashy运行或配置的支持,请查看",
|
||||
"help-support-discussions": "讨论",
|
||||
"support-dashy": "支持Dashy",
|
||||
"support-dashy-description": "了解参与Dashy项目的方式,请查看",
|
||||
"support-dashy-link": "贡献页面",
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
},
|
||||
"app-info": {
|
||||
"title": "應用程式資訊",
|
||||
"error-log": "錯誤紀錄",
|
||||
"no-errors": "近期未偵測到錯誤",
|
||||
"help-support": "幫助與支援",
|
||||
"help-support-description": "關於取得執行或設定 Dashy 的支援,請前往",
|
||||
"help-support-discussions": "討論區",
|
||||
"support-dashy": "支持 Dashy",
|
||||
"support-dashy-description": "您也能幫助 Dashy!請參閱",
|
||||
"support-dashy-link": "貢獻頁面",
|
||||
|
||||
@@ -1,55 +1,71 @@
|
||||
<template>
|
||||
<div class="about-modal">
|
||||
<router-link to="/about" class="title"><h2>{{ $t('app-info.title') }}</h2></router-link>
|
||||
<!-- Error Log -->
|
||||
<h3>{{ $t('app-info.error-log') }}</h3>
|
||||
<pre v-if="errorLog" class="logs"><code>{{ errorLog }}</code></pre>
|
||||
<p v-else>{{ $t('app-info.no-errors') }} :)</p>
|
||||
<hr />
|
||||
<!-- Getting Help -->
|
||||
<h3>{{ $t('app-info.help-support') }}</h3>
|
||||
{{ $t('app-info.help-support-description') }} <a href="https://github.com/Lissy93/dashy/discussions">{{ $t('app-info.help-support-discussions') }}</a>
|
||||
<!-- Please help out :) -->
|
||||
<h3>{{ $t('app-info.support-dashy') }}</h3>
|
||||
{{ $t('app-info.support-dashy-description') }} <a href="https://github.com/Lissy93/dashy/blob/master/docs/contributing.md">{{ $t('app-info.support-dashy-link') }}</a>.
|
||||
<!-- Bug Reports -->
|
||||
<h3>{{ $t('app-info.report-bug') }}</h3>
|
||||
{{ $t('app-info.report-bug-description') }} <a href="https://github.com/Lissy93/dashy/issues/new/choose">{{ $t('app-info.report-bug-link') }}</a>.
|
||||
<h2 class="title">{{ $t('app-info.title') }}</h2>
|
||||
<!-- Source and Docs Links -->
|
||||
<h3>{{ $t('app-info.more-info') }}</h3>
|
||||
{{ $t('app-info.source') }}: <a href="https://github.com/lissy93/dashy">github.com/lissy93/dashy</a><br>
|
||||
{{ $t('app-info.documentation') }}: <a href="https://dashy.to/docs">dashy.to/docs</a>
|
||||
{{ $t('app-info.source') }}:
|
||||
<a href="https://github.com/lissy93/dashy"
|
||||
target="_blank" rel="noopener noreferrer">github.com/lissy93/dashy</a><br>
|
||||
{{ $t('app-info.documentation') }}:
|
||||
<a href="https://dashy.to/docs"
|
||||
target="_blank" rel="noopener noreferrer">dashy.to/docs</a>
|
||||
<!-- Bug Reports -->
|
||||
<h3>{{ $t('app-info.report-bug') }}</h3>
|
||||
{{ $t('app-info.report-bug-description') }}
|
||||
<a href="#"
|
||||
@click.prevent="$emit('navigate-tab', 'debug')">{{
|
||||
$t('app-info.report-bug-debug-link') }}</a>
|
||||
{{ $t('app-info.report-bug-middle') }}
|
||||
<a href="https://github.com/Lissy93/dashy/issues/new/choose"
|
||||
target="_blank" rel="noopener noreferrer">{{ $t('app-info.report-bug-link') }}</a>.
|
||||
<!-- Please, I really need to pay my rent! -->
|
||||
<h3>{{ $t('app-info.sponsor-heading') }}</h3>
|
||||
{{ $t('app-info.sponsor-l1-prefix') }}
|
||||
<a href="https://github.com/sponsors/Lissy93"
|
||||
target="_blank" rel="noopener noreferrer">{{ $t('app-info.sponsor-l1-link') }}</a>
|
||||
{{ $t('app-info.sponsor-l1-suffix') }}
|
||||
<!-- Privacy & Security -->
|
||||
<h3>{{ $t('app-info.privacy-and-security') }}</h3>
|
||||
{{ $t('app-info.privacy-and-security-l1') }} <a href="https://github.com/Lissy93/dashy/blob/master/docs/privacy.md">{{ $t('app-info.privacy-and-security-privacy-policy') }}</a>.<br>
|
||||
{{ $t('app-info.privacy-and-security-l1') }}
|
||||
<a href="https://dashy.to/docs/privacy"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('app-info.privacy-and-security-privacy-policy') }}</a>.
|
||||
<br>
|
||||
{{ $t('app-info.privacy-and-security-advice') }}
|
||||
<a href="https://github.com/Lissy93/dashy/blob/master/docs/management.md">{{ $t('app-info.privacy-and-security-advice-link') }}</a>.<br>
|
||||
<a href="https://dashy.to/docs/management"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('app-info.privacy-and-security-advice-link') }}</a>.
|
||||
<br>
|
||||
{{ $t('app-info.privacy-and-security-security-issue') }}
|
||||
<a href="https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md">{{ $t('app-info.privacy-and-security-security-policy') }}</a>
|
||||
<a href="https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('app-info.privacy-and-security-security-policy') }}</a>
|
||||
<!-- License -->
|
||||
<h3>{{ $t('app-info.license') }}</h3>
|
||||
{{ $t('app-info.license-under') }} <a href="https://github.com/Lissy93/dashy/blob/master/LICENSE">MIT X11</a>.
|
||||
Copyright <a href="https://aliciasykes.com">Alicia Sykes</a> © {{new Date().getFullYear()}}.<br>
|
||||
{{ $t('app-info.licence-third-party') }} <a href="https://github.com/Lissy93/dashy/blob/master/.github/LEGAL.md">{{ $t('app-info.licence-third-party-link') }}</a>.<br>
|
||||
{{ $t('app-info.list-contributors') }} <a href="https://github.com/Lissy93/dashy/blob/master/docs/credits.md">{{ $t('app-info.list-contributors-link') }}</a>.
|
||||
{{ $t('app-info.license-under') }}
|
||||
<a href="https://github.com/Lissy93/dashy/blob/master/LICENSE"
|
||||
target="_blank" rel="noopener noreferrer">MIT X11</a>.
|
||||
Copyright
|
||||
<a href="https://aliciasykes.com"
|
||||
target="_blank" rel="noopener noreferrer">Alicia Sykes</a>
|
||||
© {{ new Date().getFullYear() }}.<br>
|
||||
{{ $t('app-info.list-contributors') }}
|
||||
<a href="https://github.com/Lissy93/dashy/blob/master/docs/credits.md"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('app-info.list-contributors-link') }}</a>.
|
||||
<!-- App Version -->
|
||||
<h3>{{ $t('app-info.version') }}</h3>
|
||||
<AppVersion class="app-version" />
|
||||
<AppVersion class="app-version" :doUpdateCheck="false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppVersion from '@/components/Configuration/AppVersion';
|
||||
import { sessionStorageKeys } from '@/utils/config/defaults';
|
||||
|
||||
export default {
|
||||
name: 'AppInfo',
|
||||
emits: ['navigate-tab'],
|
||||
components: { AppVersion },
|
||||
data() {
|
||||
return {
|
||||
errorLog: sessionStorage.getItem(sessionStorageKeys.ERROR_LOG) || '',
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -61,10 +77,7 @@ div.about-modal {
|
||||
padding: 0 1rem;
|
||||
height: 100%;
|
||||
p, ul li, a { font-size: 1rem; }
|
||||
a.title {
|
||||
text-decoration: none;
|
||||
h2 { font-size: 1.8rem; text-align: center; margin: 1rem; }
|
||||
}
|
||||
h2.title { font-size: 1.8rem; text-align: center; margin: 1rem; }
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0.75rem 0 0.2rem 0;
|
||||
@@ -73,17 +86,6 @@ div.about-modal {
|
||||
}
|
||||
a { color: var(--config-settings-color); }
|
||||
.app-version { text-align: left; }
|
||||
pre.logs {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
padding: 1rem;
|
||||
font-size: 0.75rem;
|
||||
border-radius: var(--curve-factor-small);
|
||||
text-align: left;
|
||||
color: var(--white);
|
||||
background: var(--black);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -92,6 +94,10 @@ div.about-modal .app-version {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: self-end;
|
||||
p { margin: 0; }
|
||||
p {
|
||||
color: var(--config-settings-color);
|
||||
font-size: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="config-buttons">
|
||||
<h2>{{ $t('config.heading') }}</h2>
|
||||
<!-- Export config button -->
|
||||
<Button class="config-button" :disallow="!enableConfig" :click="openExportConfigModal">
|
||||
<Button class="config-button" :disallow="!enableConfig" :click="openExportConfigTab">
|
||||
{{ $t('config.download-config-button') }}
|
||||
<DownloadIcon class="button-icon"/>
|
||||
</Button>
|
||||
@@ -40,6 +40,11 @@
|
||||
{{ $t('config.reset-settings-button') }}
|
||||
<DeleteIcon class="button-icon"/>
|
||||
</Button>
|
||||
<!-- Debug info button -->
|
||||
<Button class="config-button" :click="openDebugTab">
|
||||
{{ $t('config.debug-info-button') }}
|
||||
<DebugIcon class="button-icon" />
|
||||
</Button>
|
||||
<!-- About modal button -->
|
||||
<Button class="config-button" :click="openAboutTab">
|
||||
{{ $t('config.app-info-button') }}
|
||||
@@ -49,8 +54,7 @@
|
||||
<div class="instance-info">
|
||||
<p class="language-and-theme">
|
||||
{{ getLanguage() }}
|
||||
•
|
||||
{{ currentTheme ? `🎨 ${currentTheme}` : '' }}
|
||||
{{ currentTheme ? `• 🎨 ${currentTheme}` : '' }}
|
||||
</p>
|
||||
<!-- Display location of config file -->
|
||||
<p class="config-location">
|
||||
@@ -65,20 +69,26 @@
|
||||
<p class="small-screen-note" style="display: none;">{{ $t('config.small-screen-note') }}</p>
|
||||
</div>
|
||||
</TabItem>
|
||||
<TabItem :name="$t('config.edit-config-tab')" v-if="enableConfig">
|
||||
<TabItem id="edit" :name="$t('config.edit-config-tab')" v-if="enableConfig">
|
||||
<JsonEditor />
|
||||
</TabItem>
|
||||
<TabItem :name="$t('cloud-sync.title')" v-if="enableConfig">
|
||||
<CloudBackupRestore />
|
||||
<TabItem id="export" :name="$t('config.view-config-tab')" v-if="enableConfig">
|
||||
<ExportConfigMenu @navigate-tab="navigateToTabById" />
|
||||
</TabItem>
|
||||
<TabItem :name="$t('config.custom-css-tab')" v-if="enableConfig">
|
||||
<TabItem id="css" :name="$t('config.custom-css-tab')" v-if="enableConfig">
|
||||
<CustomCssEditor />
|
||||
</TabItem>
|
||||
<TabItem :name="$t('config.rebuild-app-button')" v-if="enableConfig">
|
||||
<RebuildApp />
|
||||
<TabItem id="debug" :name="$t('config.debug-info-button')" hidden>
|
||||
<DebugInfo />
|
||||
</TabItem>
|
||||
<TabItem :name="$t('config.app-info-button')">
|
||||
<AppInfo />
|
||||
<TabItem id="about" :name="$t('config.app-info-button')" hidden>
|
||||
<AppInfo @navigate-tab="navigateToTabById" />
|
||||
</TabItem>
|
||||
<TabItem id="cloud" :name="$t('cloud-sync.title')" v-if="enableConfig" hidden>
|
||||
<CloudBackupRestore />
|
||||
</TabItem>
|
||||
<TabItem id="rebuild" :name="$t('config.rebuild-app-button')" v-if="enableConfig" hidden>
|
||||
<RebuildApp />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</template>
|
||||
@@ -94,7 +104,9 @@ import CustomCssEditor from '@/components/Configuration/CustomCss';
|
||||
import CloudBackupRestore from '@/components/Configuration/CloudBackupRestore';
|
||||
import RebuildApp from '@/components/Configuration/RebuildApp';
|
||||
import AppInfo from '@/components/Configuration/AppInfo';
|
||||
import DebugInfo from '@/components/Configuration/DebugInfo';
|
||||
import AppVersion from '@/components/Configuration/AppVersion';
|
||||
import ExportConfigMenu from '@/components/InteractiveEditor/ExportConfigMenu';
|
||||
import Button from '@/components/FormElements/Button';
|
||||
import Tabs from '@/components/FormElements/Tabs';
|
||||
import TabItem from '@/components/FormElements/TabItem';
|
||||
@@ -106,6 +118,7 @@ import CloudIcon from '@/assets/interface-icons/cloud-backup-restore.svg';
|
||||
import RebuildIcon from '@/assets/interface-icons/application-rebuild.svg';
|
||||
import LanguageIcon from '@/assets/interface-icons/config-language.svg';
|
||||
import IconAbout from '@/assets/interface-icons/application-about.svg';
|
||||
import DebugIcon from '@/assets/interface-icons/config-debug-menu.svg';
|
||||
|
||||
const EditorLoading = {
|
||||
render: () => h('p', { class: 'editor-loading-placeholder' }, 'Loading editor…'),
|
||||
@@ -152,7 +165,9 @@ export default {
|
||||
CloudBackupRestore,
|
||||
RebuildApp,
|
||||
AppInfo,
|
||||
DebugInfo,
|
||||
AppVersion,
|
||||
ExportConfigMenu,
|
||||
DownloadIcon,
|
||||
DeleteIcon,
|
||||
EditIcon,
|
||||
@@ -161,6 +176,7 @@ export default {
|
||||
LanguageIcon,
|
||||
RebuildIcon,
|
||||
IconAbout,
|
||||
DebugIcon,
|
||||
},
|
||||
methods: {
|
||||
/* Progamatically navigates to a given tab by index */
|
||||
@@ -168,35 +184,44 @@ export default {
|
||||
const itemToSelect = this.$refs.tabView.navItems[tabInxex];
|
||||
this.$refs.tabView.activeTabItem(itemToSelect);
|
||||
},
|
||||
/* Navigates to a tab by its id */
|
||||
navigateToTabById(id) {
|
||||
if (!id) return;
|
||||
const items = this.$refs.tabView?.navItems || [];
|
||||
const index = items.findIndex((t) => t.id === id);
|
||||
if (index >= 0) this.navigateToTab(index);
|
||||
},
|
||||
openRebuildAppTab() {
|
||||
if (this.enableConfig) {
|
||||
this.navigateToTab(4);
|
||||
this.navigateToTabById('rebuild');
|
||||
} else {
|
||||
this.unauthorized();
|
||||
}
|
||||
},
|
||||
openAboutTab() {
|
||||
const lastIndex = this.$refs.tabView.navItems.length - 1;
|
||||
this.navigateToTab(lastIndex);
|
||||
this.navigateToTabById('about');
|
||||
},
|
||||
openDebugTab() {
|
||||
this.navigateToTabById('debug');
|
||||
},
|
||||
openLanguageSwitchModal() {
|
||||
this.$modal.show(modalNames.LANG_SWITCHER);
|
||||
},
|
||||
openExportConfigModal() {
|
||||
openExportConfigTab() {
|
||||
if (this.enableConfig) {
|
||||
this.$modal.show(modalNames.EXPORT_CONFIG_MENU);
|
||||
this.navigateToTabById('export');
|
||||
} else {
|
||||
this.unauthorized();
|
||||
}
|
||||
},
|
||||
openEditConfigTab() {
|
||||
this.navigateToTab(1);
|
||||
this.navigateToTabById('edit');
|
||||
},
|
||||
openCloudSyncTab() {
|
||||
this.navigateToTab(2);
|
||||
this.navigateToTabById('cloud');
|
||||
},
|
||||
openEditCssTab() {
|
||||
this.navigateToTab(3);
|
||||
this.navigateToTabById('css');
|
||||
},
|
||||
/* Clears config-scoped localStorage entries for root + all sub-pages, then reloads config.
|
||||
* Preserves unrelated keys (auth tokens, backup hashes, mostUsed etc) */
|
||||
@@ -214,11 +239,15 @@ export default {
|
||||
const lang = getUsersLanguage();
|
||||
return lang ? `${lang.flag} ${lang.name}` : '';
|
||||
},
|
||||
/* If launching menu from editor, navigate to correct starting tab */
|
||||
/* If launching menu from editor, navigate to correct starting tab.
|
||||
* Accepts either a numeric index (legacy) or a stable tab id string. */
|
||||
navigateToStartingTab() {
|
||||
const navToTab = this.$store.state.navigateConfToTab;
|
||||
const isValidTabIndex = (indx) => typeof indx === 'number' && indx >= 0 && indx <= 5;
|
||||
if (navToTab && isValidTabIndex(navToTab)) this.navigateToTab(navToTab);
|
||||
const navTo = this.$store.state.navigateConfToTab;
|
||||
if (typeof navTo === 'string' && navTo) {
|
||||
this.navigateToTabById(navTo);
|
||||
} else if (typeof navTo === 'number' && navTo >= 0) {
|
||||
this.navigateToTab(navTo);
|
||||
}
|
||||
this.$store.commit(StoreKeys.CONF_MENU_INDEX, undefined);
|
||||
},
|
||||
unauthorized() {
|
||||
|
||||
295
src/components/Configuration/DebugInfo.vue
Normal file
295
src/components/Configuration/DebugInfo.vue
Normal file
@@ -0,0 +1,295 @@
|
||||
<template>
|
||||
<div class="debug-info">
|
||||
<!-- Resources -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.getting-help') }}</h3>
|
||||
<p>{{ $t('debug.getting-help-msg') }}</p>
|
||||
<ul>
|
||||
<li v-for="r in resources" :key="r.id">
|
||||
<a :href="r.url" target="_blank" rel="noopener noreferrer">{{
|
||||
$t(`debug.resources.${r.id}-name`) }}</a>
|
||||
- <i v-if="r.noteKey">{{ $t(`debug.resources.${r.noteKey}`) }}</i>
|
||||
{{ $t(`debug.resources.${r.id}-desc`) }}
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- Raising bugs -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.reporting-bug') }}</h3>
|
||||
<p>
|
||||
{{ $t('debug.reporting-bug-l1-prefix') }}
|
||||
<a href="https://github.com/Lissy93/dashy/issues/new/choose"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('debug.reporting-bug-l1-link') }}</a>
|
||||
{{ $t('debug.reporting-bug-l1-suffix') }}
|
||||
</p>
|
||||
<p>{{ $t('debug.reporting-bug-l2-intro') }}</p>
|
||||
<ul>
|
||||
<li v-for="item in bugReportItems" :key="item">
|
||||
{{ $t(`debug.reporting-bug-list.${item}`) }}
|
||||
</li>
|
||||
</ul>
|
||||
<p class="hint">{{ $t('debug.reporting-bug-note') }}</p>
|
||||
</section>
|
||||
|
||||
<!-- App Version -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.app-version') }}</h3>
|
||||
<AppVersion class="version-block" />
|
||||
</section>
|
||||
|
||||
<!-- Error Log -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.error-log') }}</h3>
|
||||
<p class="hint">
|
||||
{{ $t('debug.error-log-hint-prefix') }}
|
||||
<a href="https://dashy.to/docs/troubleshooting/#how-to-open-browser-console"
|
||||
target="_blank" rel="noopener noreferrer">{{
|
||||
$t('debug.error-log-hint-link') }}</a>
|
||||
{{ $t('debug.error-log-hint-suffix') }}
|
||||
</p>
|
||||
<pre v-if="errorLog" class="log-block"><code>{{ errorLog }}</code></pre>
|
||||
<p v-else class="empty">{{ $t('debug.no-errors') }}</p>
|
||||
</section>
|
||||
|
||||
<!-- Current Config -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.current-config') }}</h3>
|
||||
<p class="hint">{{ $t('debug.current-config-hint') }}</p>
|
||||
<pre class="log-block"><code>{{ currentConfigYaml }}</code></pre>
|
||||
</section>
|
||||
|
||||
<!-- Local Storage -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.local-storage') }}</h3>
|
||||
<p class="hint">{{ $t('debug.local-storage-hint') }}</p>
|
||||
<pre v-if="localStorageDump" class="log-block"><code>{{ localStorageDump }}</code></pre>
|
||||
<p v-else class="empty">{{ $t('debug.no-local-storage') }}</p>
|
||||
</section>
|
||||
|
||||
<!-- Environment -->
|
||||
<section>
|
||||
<h3>{{ $t('debug.environment') }}</h3>
|
||||
<p class="hint">{{ $t('debug.environment-hint') }}</p>
|
||||
<dl class="env-grid">
|
||||
<template v-for="row in envRows" :key="row.key">
|
||||
<dt>{{ $t(`debug.env.${row.key}`) }}</dt>
|
||||
<dd>{{ row.value }}</dd>
|
||||
</template>
|
||||
</dl>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { dump as yamlDump } from 'js-yaml';
|
||||
import AppVersion from '@/components/Configuration/AppVersion';
|
||||
import { sessionStorageKeys } from '@/utils/config/defaults';
|
||||
import { ErrorHandler } from '@/utils/logging/ErrorHandler';
|
||||
|
||||
const RESOURCES = [
|
||||
{ id: 'troubleshooting', url: 'https://dashy.to/docs/troubleshooting/' },
|
||||
{ id: 'docs', url: 'https://dashy.to/docs/' },
|
||||
{ id: 'source', url: 'https://github.com/Lissy93/dashy/' },
|
||||
{ id: 'email', url: 'mailto:dashy-support@mail.as93.net', noteKey: 'email-note' },
|
||||
];
|
||||
|
||||
const BUG_REPORT_ITEMS = ['version', 'deployment', 'errors', 'config', 'overrides', 'environment'];
|
||||
|
||||
/* Sensitive keys whose values are hidden in the debug view (still listed by name) */
|
||||
const REDACTED_KEYS = ['keycloakInfo', 'backupHash'];
|
||||
const isRedacted = (key) => REDACTED_KEYS.some((k) => key === k || key.startsWith(`${k}_`));
|
||||
|
||||
/* Run a getter, returning its value or the supplied fallback on error/empty */
|
||||
const safe = (label, fn, fallback) => {
|
||||
try {
|
||||
const v = fn();
|
||||
return v == null || v === '' ? fallback : v;
|
||||
} catch (e) {
|
||||
ErrorHandler(`Failed to read env info '${label}': ${e.message}`);
|
||||
return fallback;
|
||||
}
|
||||
};
|
||||
|
||||
/* Parse a friendly browser label from a UA string. Returns null if unrecognised. */
|
||||
const parseBrowser = (ua) => {
|
||||
if (!ua) return null;
|
||||
const major = (re) => ((ua.match(re) || [])[1] || '').split('.')[0];
|
||||
if (/Edg\//.test(ua)) return `Edge ${major(/Edg\/(\S+)/)}`.trim();
|
||||
if (/OPR\//.test(ua)) return `Opera ${major(/OPR\/(\S+)/)}`.trim();
|
||||
if (/Firefox\//.test(ua)) return `Firefox ${major(/Firefox\/(\S+)/)}`.trim();
|
||||
if (/Chrome\//.test(ua)) return `Chrome ${major(/Chrome\/(\S+)/)}`.trim();
|
||||
if (/Safari\//.test(ua)) return `Safari ${major(/Version\/(\S+)/)}`.trim();
|
||||
return null;
|
||||
};
|
||||
|
||||
/* Parse a friendly OS label from a UA string. Returns null if unrecognised. */
|
||||
const parseOs = (ua) => {
|
||||
if (!ua) return null;
|
||||
if (/Windows NT/.test(ua)) {
|
||||
const v = (ua.match(/Windows NT (\d+\.\d+)/) || [])[1];
|
||||
const map = { '10.0': '10/11', '6.3': '8.1', '6.2': '8', '6.1': '7' };
|
||||
return `Windows ${map[v] || v || ''}`.trim();
|
||||
}
|
||||
if (/Mac OS X/.test(ua)) {
|
||||
const v = (ua.match(/Mac OS X (\d+[._]\d+)/) || [])[1] || '';
|
||||
return `macOS ${v.replace(/_/g, '.')}`.trim();
|
||||
}
|
||||
if (/iPhone|iPad|iPod/.test(ua)) return 'iOS';
|
||||
if (/Android/.test(ua)) return `Android ${(ua.match(/Android (\d+)/) || [])[1] || ''}`.trim();
|
||||
if (/Linux/.test(ua)) return 'Linux';
|
||||
return null;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'DebugInfo',
|
||||
components: { AppVersion },
|
||||
data() {
|
||||
return {
|
||||
resources: RESOURCES,
|
||||
bugReportItems: BUG_REPORT_ITEMS,
|
||||
errorLog: sessionStorage.getItem(sessionStorageKeys.ERROR_LOG) || '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* The current config being used */
|
||||
currentConfigYaml() {
|
||||
try {
|
||||
return yamlDump(this.$store.state.configSource);
|
||||
} catch (e) {
|
||||
return this.$t('debug.config-render-error', { error: String(e) });
|
||||
}
|
||||
},
|
||||
/* Gets dump of local overrides */
|
||||
localStorageDump() {
|
||||
try {
|
||||
const entries = Object.keys(localStorage).sort().map((key) => {
|
||||
if (isRedacted(key)) return [key, '[redacted]'];
|
||||
const raw = localStorage.getItem(key);
|
||||
try { return [key, JSON.parse(raw)]; } catch { return [key, raw]; }
|
||||
});
|
||||
return entries.length ? JSON.stringify(Object.fromEntries(entries), null, 2) : '';
|
||||
} catch (e) {
|
||||
return this.$t('debug.local-storage-error', { error: String(e) });
|
||||
}
|
||||
},
|
||||
/* Shows user basic environment info */
|
||||
envRows() {
|
||||
const ua = (typeof navigator !== 'undefined' && navigator.userAgent) || '';
|
||||
const unknown = this.$t('debug.env.unknown');
|
||||
const yes = this.$t('debug.env.yes');
|
||||
const no = this.$t('debug.env.no');
|
||||
const yn = (cond) => (cond ? yes : no);
|
||||
const probes = [
|
||||
['browser', () => parseBrowser(ua)],
|
||||
['os', () => parseOs(ua) || navigator.userAgentData?.platform],
|
||||
['viewport', () => `${window.innerWidth} × ${window.innerHeight}`],
|
||||
['screen', () => `${window.screen.width} × ${window.screen.height}`],
|
||||
['dpr', () => `${window.devicePixelRatio}x`],
|
||||
['languages',
|
||||
() => (navigator.languages || [navigator.language]).filter(Boolean).join(', ')],
|
||||
['timezone', () => Intl.DateTimeFormat().resolvedOptions().timeZone],
|
||||
['colorScheme',
|
||||
() => (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')],
|
||||
['reducedMotion',
|
||||
() => yn(window.matchMedia('(prefers-reduced-motion: reduce)').matches)],
|
||||
['online', () => yn(navigator.onLine)],
|
||||
['route', () => window.location.pathname],
|
||||
['mode', () => import.meta.env.MODE],
|
||||
['swActive', () => yn(!!navigator.serviceWorker?.controller)],
|
||||
];
|
||||
return probes.map(([key, get]) => ({ key, value: safe(key, get, unknown) }));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.debug-info {
|
||||
padding: 1rem 1.25rem;
|
||||
background: var(--config-settings-background);
|
||||
color: var(--config-settings-color);
|
||||
|
||||
ul {
|
||||
margin: 0.5rem 0;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
section + section {
|
||||
margin-top: 1.25rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px dashed var(--config-settings-color);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
p { margin: 0; line-height: 1.5; }
|
||||
p + p { margin-top: 0.5rem; }
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
&:hover, &:focus-visible { text-decoration: underline; }
|
||||
}
|
||||
|
||||
.empty {
|
||||
opacity: 0.6;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hint {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.log-block {
|
||||
margin: 0;
|
||||
padding: 0.75rem 1rem;
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
font-family: var(--font-monospace);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.4;
|
||||
color: var(--white);
|
||||
background: var(--black);
|
||||
border-radius: var(--curve-factor-small);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.env-grid {
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 0.4rem 1.25rem;
|
||||
margin: 0;
|
||||
align-items: baseline;
|
||||
dt {
|
||||
font-weight: 600;
|
||||
opacity: 0.7;
|
||||
}
|
||||
dd {
|
||||
margin: 0;
|
||||
font-family: var(--font-monospace);
|
||||
font-size: 0.85rem;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.debug-info .version-block {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15rem;
|
||||
p { margin: 0; text-align: left; }
|
||||
}
|
||||
</style>
|
||||
@@ -125,6 +125,8 @@ dialog.dashy-modal {
|
||||
min-height: 200px;
|
||||
max-width: 95vw;
|
||||
max-height: 95vh;
|
||||
max-width: 72rem;
|
||||
max-height: 72rem;
|
||||
color: inherit;
|
||||
background: var(--background-darker);
|
||||
border: none;
|
||||
@@ -9,6 +9,8 @@ export default {
|
||||
name: 'TabItem',
|
||||
props: {
|
||||
name: { type: String, required: true },
|
||||
id: { type: String, default: '' },
|
||||
hidden: { type: Boolean, default: false },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<div class="tab__pagination" role="tablist">
|
||||
<button
|
||||
v-for="(item, index) in navItems"
|
||||
v-show="!item.hidden"
|
||||
:key="index"
|
||||
class="tab__nav__item"
|
||||
:class="{ active: activeIndex === index }"
|
||||
@@ -37,19 +38,22 @@ export default {
|
||||
if (!defaultSlot) return [];
|
||||
const vnodes = defaultSlot();
|
||||
const items = [];
|
||||
const push = (node) => {
|
||||
if (!node.props?.name) return;
|
||||
items.push({
|
||||
name: node.props.name,
|
||||
id: node.props.id || '',
|
||||
hidden: node.props.hidden === '' || node.props.hidden === true,
|
||||
vnode: { render: () => h(node) },
|
||||
});
|
||||
};
|
||||
vnodes.forEach((vnode) => {
|
||||
if (!vnode.type || vnode.type === Symbol.for('v-cmt')) return;
|
||||
if (vnode.type === Symbol.for('v-fgt') && Array.isArray(vnode.children)) {
|
||||
vnode.children.forEach((child) => {
|
||||
if (child.props?.name) {
|
||||
items.push({ name: child.props.name, vnode: { render: () => h(child) } });
|
||||
}
|
||||
});
|
||||
vnode.children.forEach(push);
|
||||
return;
|
||||
}
|
||||
if (vnode.props?.name) {
|
||||
items.push({ name: vnode.props.name, vnode: { render: () => h(vnode) } });
|
||||
}
|
||||
push(vnode);
|
||||
});
|
||||
return items;
|
||||
},
|
||||
@@ -60,14 +64,19 @@ export default {
|
||||
if (index >= 0) this.activeIndex = index;
|
||||
},
|
||||
onKeydown(e, index) {
|
||||
const len = this.navItems.length;
|
||||
let next = -1;
|
||||
if (e.key === 'ArrowRight') next = (index + 1) % len;
|
||||
else if (e.key === 'ArrowLeft') next = (index - 1 + len) % len;
|
||||
else if (e.key === 'Home') next = 0;
|
||||
else if (e.key === 'End') next = len - 1;
|
||||
if (next >= 0) {
|
||||
const visible = this.navItems
|
||||
.map((item, i) => ({ item, i }))
|
||||
.filter(({ item }) => !item.hidden);
|
||||
if (!visible.length) return;
|
||||
const pos = visible.findIndex(({ i }) => i === index);
|
||||
let nextPos = -1;
|
||||
if (e.key === 'ArrowRight') nextPos = (pos + 1) % visible.length;
|
||||
else if (e.key === 'ArrowLeft') nextPos = (pos - 1 + visible.length) % visible.length;
|
||||
else if (e.key === 'Home') nextPos = 0;
|
||||
else if (e.key === 'End') nextPos = visible.length - 1;
|
||||
if (nextPos >= 0) {
|
||||
e.preventDefault();
|
||||
const next = visible[nextPos].i;
|
||||
this.activeIndex = next;
|
||||
this.$el.querySelectorAll('[role="tab"]')[next]?.focus();
|
||||
}
|
||||
|
||||
@@ -163,7 +163,8 @@ export default {
|
||||
this.$store.commit(StoreKeys.SET_EDIT_MODE, false);
|
||||
},
|
||||
openExportConfigMenu() {
|
||||
this.$modal.show(modalNames.EXPORT_CONFIG_MENU);
|
||||
this.$store.commit(StoreKeys.CONF_MENU_INDEX, 2);
|
||||
this.$modal.show(modalNames.CONF_EDITOR);
|
||||
this.$store.commit(StoreKeys.SET_MODAL_OPEN, true);
|
||||
},
|
||||
openEditPageInfo() {
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
<template>
|
||||
<modal
|
||||
:name="modalName"
|
||||
:resizable="true"
|
||||
width="75%"
|
||||
height="75%"
|
||||
classes="dashy-modal export-modal"
|
||||
@before-open="buildRows"
|
||||
@closed="modalClosed"
|
||||
>
|
||||
<div class="export-config-wrapper">
|
||||
<div class="export-config-inner" v-if="allowViewConfig">
|
||||
<section class="current-config">
|
||||
<h3>{{ $t('interactive-editor.export.current-config-title') }}</h3>
|
||||
@@ -108,14 +100,12 @@
|
||||
</section>
|
||||
</div>
|
||||
<AccessError v-else />
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { load as yamlLoad, dump as yamlDump } from 'js-yaml';
|
||||
import Button from '@/components/FormElements/Button';
|
||||
import StoreKeys from '@/utils/StoreMutations';
|
||||
import { modalNames } from '@/utils/config/defaults';
|
||||
import AccessError from '@/components/Configuration/AccessError';
|
||||
import DownloadConfigIcon from '@/assets/interface-icons/config-download-file.svg';
|
||||
import CopyConfigIcon from '@/assets/interface-icons/interactive-editor-copy-clipboard.svg';
|
||||
@@ -142,6 +132,7 @@ const basename = (path) => {
|
||||
|
||||
export default {
|
||||
name: 'ExportConfigMenu',
|
||||
emits: ['navigate-tab'],
|
||||
components: {
|
||||
Button,
|
||||
AccessError,
|
||||
@@ -152,12 +143,14 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modalName: modalNames.EXPORT_CONFIG_MENU,
|
||||
previewOpen: false,
|
||||
expandedRow: null,
|
||||
rows: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.buildRows();
|
||||
},
|
||||
computed: {
|
||||
config() {
|
||||
return this.$store.state.configSource;
|
||||
@@ -285,21 +278,14 @@ export default {
|
||||
},
|
||||
openConfig(row) {
|
||||
const target = makeRoutePath('home', row.isRoot ? null : row.id);
|
||||
// this.$modal.hide(this.modalName);
|
||||
if (this.$route.path !== target) this.$router.push(target);
|
||||
},
|
||||
editCurrent() {
|
||||
this.$modal.hide(this.modalName);
|
||||
this.$store.commit(StoreKeys.CONF_MENU_INDEX, 2);
|
||||
this.$modal.show(modalNames.CONF_EDITOR);
|
||||
this.$store.commit(StoreKeys.SET_MODAL_OPEN, true);
|
||||
this.$emit('navigate-tab', 'edit');
|
||||
},
|
||||
rawPathHref(row) {
|
||||
return formatConfigPath(row.path);
|
||||
},
|
||||
modalClosed() {
|
||||
this.$store.commit(StoreKeys.SET_MODAL_OPEN, false);
|
||||
},
|
||||
tooltip(content) {
|
||||
return { content, popperClass: 'in-modal-tt' };
|
||||
},
|
||||
@@ -479,7 +465,4 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.export-modal {
|
||||
background: var(--interactive-editor-background);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,7 +41,8 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
exportConfig() {
|
||||
this.$modal.show(modalNames.EXPORT_CONFIG_MENU);
|
||||
this.$store.commit(StoreKeys.CONF_MENU_INDEX, 2);
|
||||
this.$modal.show(modalNames.CONF_EDITOR);
|
||||
this.shouldHide = true;
|
||||
},
|
||||
saveConfig() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import VSelect from 'vue-select'; // Select dropdown component
|
||||
|
||||
// Import base Dashy components and utils
|
||||
import Dashy from '@/App.vue'; // Main Dashy Vue app
|
||||
import Modal from '@/components/Modal.vue'; // In-house modal component
|
||||
import Modal from '@/components/FormElements/Modal.vue'; // In-house modal component
|
||||
import VModal from '@/plugins/modal'; // $modal.show()/hide() plugin
|
||||
import store from '@/store'; // Store, for local state management
|
||||
import router from '@/router'; // Router, for navigation
|
||||
|
||||
@@ -92,11 +92,6 @@ const router = createRouter({
|
||||
next();
|
||||
},
|
||||
},
|
||||
{ // The about app page
|
||||
path: routePaths.about,
|
||||
name: 'about', // We lazy load the About page so as to not slow down the app
|
||||
component: () => import('./views/About.vue'),
|
||||
},
|
||||
{ // The export config page
|
||||
path: routePaths.download,
|
||||
name: 'download',
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
--widget-accent-color: var(--background);
|
||||
--widget-base-background: transparent;
|
||||
// Interactive editor
|
||||
--interactive-editor-color: var(--primary);
|
||||
--interactive-editor-color: var(--foreground);
|
||||
--interactive-editor-background: var(--background);
|
||||
--interactive-editor-background-darker: var(--background-darker);
|
||||
// Cloud backup/ restore menu
|
||||
|
||||
@@ -31,7 +31,6 @@ const defaults = {
|
||||
home: '/home',
|
||||
minimal: '/minimal',
|
||||
workspace: '/workspace',
|
||||
about: '/about',
|
||||
login: '/login',
|
||||
download: '/download',
|
||||
notFound: '/404',
|
||||
@@ -114,7 +113,7 @@ const defaults = {
|
||||
['#636363', '#363636', '#313941', '#0d0d0d'],
|
||||
],
|
||||
/* Which CSS variables to show in the first view of theme configurator */
|
||||
mainCssVars: ['primary', 'background', 'background-darker'],
|
||||
mainCssVars: ['primary', 'foreground', 'background', 'background-darker'],
|
||||
/* Which structural components should be visible by default */
|
||||
visibleComponents: {
|
||||
splashScreen: false,
|
||||
@@ -168,7 +167,6 @@ const defaults = {
|
||||
EDIT_PAGE_INFO: 'EDIT_PAGE_INFO',
|
||||
EDIT_APP_CONFIG: 'EDIT_APP_CONFIG',
|
||||
EDIT_MULTI_PAGES: 'EDIT_MULTI_PAGES',
|
||||
EXPORT_CONFIG_MENU: 'EXPORT_CONFIG_MENU',
|
||||
MOVE_ITEM_TO: 'MOVE_ITEM_TO',
|
||||
},
|
||||
/* Key names for the top-level objects in conf.yml */
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<article class="about">
|
||||
<h1>About Dashy</h1>
|
||||
<section>
|
||||
<h2>Project Overview</h2>
|
||||
<p>
|
||||
Dashy is a self-hosted startpage for keeping your running applications and
|
||||
services organised. The aim of Dashy is to provide an easy-to-deploy,
|
||||
highly customizable and functianl dashboard, in order to improvde productivity
|
||||
and enable easy organisation of running services or web links.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Source</h2>
|
||||
<p>
|
||||
Dashy's source is available through <a href="https://github.com/lissy93/dashy">GitHub</a>,
|
||||
and the Docker image is on <a href="https://hub.docker.com/r/lissy93/dashy">DockerHub</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Reporting a Bug</h2>
|
||||
<p>
|
||||
If you've come across an bug in Dashy, please <a href="https://git.io/JnqPR">open an issue</a>,
|
||||
so that it can be fixed.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Getting Support</h2>
|
||||
<p>
|
||||
If you need any help deploying, using, or developing Dashy, feel free to
|
||||
<a href="https://git.io/JnqiA">open a support ticket</a> or start a
|
||||
<a href="https://github.com/Lissy93/dashy/discussions">discussion</a> on GitHub.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>About the Author</h2>
|
||||
<a href="https://aliciasykes.com">
|
||||
<img class="aht-pic" src="https://i.ibb.co/FnxqTfx/aht-bot-round.png" alt="Alicia Sykes">
|
||||
</a>
|
||||
Dashy is developed an maintained by <a href="https://aliciasykes.com">Alicia Sykes</a>
|
||||
(<a href="https://github.com/lissy93">@Lissy93</a>), with support from the community.
|
||||
<ul>
|
||||
<li><b>PGP Key</b> - <a href="https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7"><code>0688 F8D3 4587 D954 E9E5 1FB8 FEDB 68F5 5C02 83A7</code></a></li>
|
||||
<li><b>BTC Address</b> - <code>3853bSxupMjvxEYfwGDGAaLZhTKxB2vEVC</code></li>
|
||||
<li><b>Mail</b> - <code>alicia at omg dot lol</code></li>
|
||||
<li><b>Blog</b> - <a href="https://notes.aliciasykes.com">notes.aliciasykes.com</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="license">
|
||||
<h2>License</h2>
|
||||
<code>
|
||||
Copyright © {{new Date().getFullYear()}} Alicia Sykes (https://aliciasykes.com)
|
||||
</code>
|
||||
<br><br>
|
||||
<code>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the “Software”), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
</code>
|
||||
<br><br>
|
||||
<code>
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
</code>
|
||||
<br><br>
|
||||
<code>
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWAREOR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</code>
|
||||
</section>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-theme', 'callisto');
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
article.about {
|
||||
background: var(--about-page-background);
|
||||
color: var(--about-page-color);
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
margin: 1rem auto 2.5rem auto;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--about-page-accent);
|
||||
border-radius: var(--curve-factor);
|
||||
h1, h2, h3, p, span, div, section {
|
||||
color: var(--about-page-color);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
a, code {
|
||||
color: var(--about-page-accent);
|
||||
}
|
||||
section {
|
||||
padding-bottom: 1rem;
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--about-page-accent);
|
||||
}
|
||||
}
|
||||
p {
|
||||
line-height: 1.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
img.aht-pic {
|
||||
width: 100px;
|
||||
float: right;
|
||||
}
|
||||
section.license code {
|
||||
color: var(--about-page-color);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -43,8 +43,6 @@
|
||||
</div>
|
||||
<!-- Show banner at bottom of screen, for Saving config changes -->
|
||||
<EditModeSaveMenu v-if="isEditMode" />
|
||||
<!-- Modal for viewing and exporting configuration file -->
|
||||
<ExportConfigMenu />
|
||||
<!-- Shows pertinent info -->
|
||||
<NotificationThing v-if="$store.state.isUsingLocalConfig"/>
|
||||
</div>
|
||||
@@ -65,7 +63,6 @@ import ErrorHandler from '@/utils/logging/ErrorHandler';
|
||||
import BackIcon from '@/assets/interface-icons/back-arrow.svg';
|
||||
|
||||
const EditModeSaveMenu = defineAsyncComponent(() => import('@/components/InteractiveEditor/EditModeSaveMenu.vue'));
|
||||
const ExportConfigMenu = defineAsyncComponent(() => import('@/components/InteractiveEditor/ExportConfigMenu.vue'));
|
||||
const AddNewSection = defineAsyncComponent(() => import('@/components/InteractiveEditor/AddNewSectionLauncher.vue'));
|
||||
|
||||
export default {
|
||||
@@ -74,7 +71,6 @@ export default {
|
||||
components: {
|
||||
SettingsContainer,
|
||||
EditModeSaveMenu,
|
||||
ExportConfigMenu,
|
||||
AddNewSection,
|
||||
NotificationThing,
|
||||
Section,
|
||||
|
||||
Reference in New Issue
Block a user