Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Custom Error Pages #257

Merged
merged 8 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## ✨ 1.8.4 - Custom Error Pages [PR #257](https://github.com/Lissy93/dashy/pull/257)
- Creates a 404 Not Found page
- Routes any missing views to the 404 page

## ⚡️ 1.8.3 - Improved UX for Initial Load [PR #238](https://github.com/Lissy93/dashy/pull/238)
- Removes the old splash screen
- Adds placeholder in the HTML index, which will usually be visible on initial load
Expand Down
10 changes: 7 additions & 3 deletions .github/SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# SUPPORT
# Support

For help with getting Dashy up and running, please see the [Discussion](https://github.com/Lissy93/dashy/discussions).
To raise a bug, please **[Open a new Issue](https://github.com/Lissy93/dashy/issues/new/choose)**.

If you'd like to help support Dashy's future development, see [Contributing](/docs/contributing.md)
To report a potential vulnerability, please see **[Security](https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md#reporting-a-security-issue)**.

For help with getting Dashy up and running, please see the **[Discussions](https://github.com/Lissy93/dashy/discussions)**.

If you'd like to help support Dashy's future development, see **[Contributing](https://github.com/Lissy93/dashy/blob/master/docs/contributing.md)**.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Dashy",
"version": "1.8.3",
"version": "1.8.4",
"license": "MIT",
"main": "server",
"scripts": {
Expand Down
133 changes: 19 additions & 114 deletions src/components/Configuration/AppInfoModal.vue
Original file line number Diff line number Diff line change
@@ -1,46 +1,32 @@
<template>
<modal :name="modalName" :resizable="true" width="60%" height="60%" classes="dashy-modal">
<modal :name="modalName" :resizable="true" width="55%" height="80%" classes="dashy-modal">
<div class="about-modal">
<router-link to="/about" class="title"><h2>App Info</h2></router-link>
<!-- App Version -->
<h3>Version</h3>
<AppVersion class="app-version" />
<!-- Error Log -->
<h3>Error Log</h3>
<pre v-if="errorLog" class="logs"><code>{{ errorLog }}</code></pre>
<p v-else>No recent errors detected :)</p>
<!-- Service Worker Status -->
<h3>Service Worker Status</h3>
<pre class="logs"><code>{{ serviceWorkerInfo }}</code></pre>
<!-- Config Validation Status -->
<h3>Config Validation Status</h3>
<pre class="logs"><code>{{getIsConfigValidStatus()}}</code></pre>
<hr />
<!-- Help Links -->
<h3>Help & Support</h3>
<ul>
<li><a href="https://github.com/Lissy93/dashy/discussions">Get Support</a></li>
<li><a href="https://github.com/Lissy93/dashy/issues/new/choose">Report a Bug</a></li>
</ul>
<span class="small-note">Please include the following info in your bug report: </span>
<a class="info" @click="showInfo = !showInfo">{{ showInfo ? 'Hide' : 'Show'}} system info</a>
<div class="system-info" v-if="showInfo">
<h4>System Info</h4>
<code><b>Dashy Version:</b> V {{appVersion}}</code><br>
<code><b>Browser:</b> {{systemInfo.browser}}</code><br>
<code><b>Is Mobile?</b> {{systemInfo.isMobile ? 'Yes' : 'No'}}</code><br>
<code><b>OS:</b> {{systemInfo.os}}</code><br>
</div>
<!-- About App -->
<h3>About</h3>
<p class="about-text">
Source: <a href="https://github.com/lissy93/dashy">github.com/lissy93/dashy</a><br>
Documentation: <a href="https://dashy.to/docs">dashy.to/docs</a>
</p>
For getting support with running or configuring Dashy, see the <a href="https://github.com/Lissy93/dashy/discussions">Discussions</a>
<h3>Report a Bug</h3>
If you think you've found a bug, then please <a href="https://github.com/Lissy93/dashy/issues/new/choose">raise it on GitHub</a>.
<br>Include version you are running, environment info, output of the console (press F12),
and any suppoting scerenshots.
<h3>Supporting Dashy</h3>
For ways that you can get involved, check out the <a href="https://github.com/Lissy93/dashy/blob/master/docs/contributing.md">Contributing</a> page.
<h3>More Info</h3>
Source: <a href="https://github.com/lissy93/dashy">github.com/lissy93/dashy</a><br>
Documentation: <a href="https://dashy.to/docs">dashy.to/docs</a>
<!-- License -->
<h3>License</h3>
<p>Licensed under MIT X11. Copyright © 2021</p>
<br><br>
Licensed under MIT X11. Copyright <a href="https://aliciasykes.com">Alicia Sykes</a> © 2021.<br>
For licenses for third-party modules, please see <a href="https://github.com/Lissy93/dashy/blob/master/.github/LEGAL.md">Legal</a>.
For a list of contributors, and application thank-you's, see <a href="https://github.com/Lissy93/dashy/blob/master/docs/credits.md">Credits</a>
<!-- App Version -->
<h3>Version</h3>
<AppVersion class="app-version" />
</div>
</modal>
</template>
Expand All @@ -58,71 +44,13 @@ export default {
return {
modalName: modalNames.ABOUT_APP,
appVersion: process.env.VUE_APP_VERSION,
systemInfo: this.getSystemInfo(),
errorLog: this.getErrorLog(),
serviceWorkerInfo: 'Checking...',
showInfo: false,
};
},
mounted() {
setTimeout(() => {
this.serviceWorkerInfo = this.getSwStatus();
}, 100);
},
methods: {
getErrorLog() {
return sessionStorage.getItem(sessionStorageKeys.ERROR_LOG) || '';
},
getIsConfigValidStatus() {
const isValidVar = process.env.VUE_APP_CONFIG_VALID;
if (isValidVar === undefined) return 'Config validation status is missing';
return `Config is ${isValidVar ? 'Valid' : 'Invalid'}`;
},
getSwStatus() {
const sessionData = sessionStorage[sessionStorageKeys.SW_STATUS];
const swInfo = sessionData ? JSON.parse(sessionData) : {};
let swStatus = '';
if (swInfo.registered) swStatus += 'Service worker registered\n';
if (swInfo.ready) swStatus += 'Dashy is being served from service worker\n';
if (swInfo.cached) swStatus += 'Content has been cached for offline use\n';
if (swInfo.updateFound) swStatus += 'New content is downloading\n';
if (swInfo.updated) swStatus += 'New content is available; please refresh\n';
if (swInfo.offline) swStatus += 'No internet connection found. App is running in offline mode\n';
if (swInfo.error) swStatus += 'Error during service worker registration\n';
if (swInfo.devMode) swStatus += 'App running in dev mode, no need for service worker\n';
if (swStatus.length === 0) swStatus += 'No service worker info available';
return swStatus;
},
getSystemInfo() {
const { userAgent } = navigator;

// Find Operating System
let os = 'Unknown';
if (userAgent.indexOf('Win') !== -1) os = 'Windows';
else if (userAgent.indexOf('Mac') !== -1) os = 'MacOS';
else if (userAgent.indexOf('Android') !== -1) os = 'Android';
else if (userAgent.indexOf('iPhone') !== -1) os = 'iOS';
else if (userAgent.indexOf('Linux') !== -1) os = 'Linux';
else if (userAgent.indexOf('X11') !== -1) os = 'UNIX';

// Find Browser
let browser = 'Unknown';
if (userAgent.indexOf('Opera') !== -1) browser = 'Opera';
else if (userAgent.indexOf('Chrome') !== -1) browser = 'Chrome';
else if (userAgent.indexOf('Safari') !== -1) browser = 'Safari';
else if (userAgent.indexOf('Firefox') !== -1) browser = 'Firefox';
else if (userAgent.indexOf('MSIE') !== -1) browser = 'IE';
else browser = 'Unknown';

const isMobile = !!navigator.userAgent.match(/iphone|android|blackberry/ig) || false;

return {
os,
browser,
userAgent,
isMobile,
};
},
},
};
</script>
Expand Down Expand Up @@ -152,40 +80,17 @@ div.about-modal {
}
}
h3 {
font-size: 1.3rem;
margin: 1rem 0 0.2rem 0;
font-size: 1rem;
margin: 0.5rem 0 0.2rem 0;
color: var(--about-page-accent);
}
p.small-note {
margin: 0.2rem 0;
}
p.about-text {
margin: 0.2rem 0;
}
a {
color: var(--about-page-accent);
}
ul {
margin-top: 0.2rem;
}
a.info {
text-decoration: underline;
margin-left: 0.2rem;
}
.system-info {
font-size: 0.8rem;
background: var(--black);
color: var(--white);
border-radius: var(--curve-factor-small);
padding: 0.5rem;
border: 1px solid var(--white);
width: fit-content;
h4 {
font-size: 0.8rem;
margin: 0 0 0.2rem 0;
text-decoration: underline;
}
}
.app-version {
text-align: left;
}
Expand Down
24 changes: 20 additions & 4 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import Vue from 'vue';
import Router from 'vue-router';
import ProgressBar from 'rsup-progress';

// Import views
// Import views, that are not lazy-loaded
import Home from '@/views/Home.vue';
import Login from '@/views/Login.vue';
import Workspace from '@/views/Workspace.vue';
import Minimal from '@/views/Minimal.vue';
import DownloadConfig from '@/views/DownloadConfig.vue';

// Import helper functions, config data and defaults
import { isAuthEnabled, isLoggedIn, isGuestAccessEnabled } from '@/utils/Auth';
import { config } from '@/utils/ConfigHelpers';
import { metaTagData, startingView, routePaths } from '@/utils/defaults';
import ErrorHandler from '@/utils/ErrorHandler';

Vue.use(Router);
const progress = new ProgressBar({ color: 'var(--progress-bar)' });
Expand Down Expand Up @@ -102,16 +102,32 @@ const router = new Router({
{ // 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(/* webpackChunkName: "about" */ './views/About.vue'),
component: () => import('./views/About.vue'),
meta: makeMetaTags('About Dashy'),
},
{ // The export config page
path: routePaths.download,
name: 'download',
component: DownloadConfig,
component: () => import('./views/DownloadConfig.vue'),
props: config,
meta: makeMetaTags('Download Config'),
},
{ // Page not found, any non-defined routes will land here
path: routePaths.notFound,
name: '404',
component: () => import('./views/404.vue'),
meta: makeMetaTags('404 Not Found'),
beforeEnter: (to, from, next) => {
if (to.redirectedFrom) { // Log error, if redirected here from another route
ErrorHandler(`Route not found: '${to.redirectedFrom}'`);
}
next();
},
},
{ // Redirect any not-found routed to the 404 view
path: '*',
redirect: '/404',
},
],
});

Expand Down
2 changes: 2 additions & 0 deletions src/utils/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = {
about: '/about',
login: '/login',
download: '/download',
notFound: '/404',
},
/* Server Endpoints */
serviceEndpoints: {
Expand Down Expand Up @@ -84,6 +85,7 @@ module.exports = {
'login',
'download',
'landing-page-minimal',
// '404',
],
/* Key names for local storage identifiers */
localStorageKeys: {
Expand Down
90 changes: 90 additions & 0 deletions src/views/404.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<template>
<main class="not-found-page">
<h1 class="not-found-title">404</h1>
<h2 class="not-found-sad-face">:(</h2>
<p class="not-found-subtitle">Page Not Found</p>
<p class="not-found-message">
Facing Issues?
<a href="https://git.io/JzpL5">Get Support</a>.
</p>
<router-link to="/" class="go-home">Back Home</router-link>
</main>
</template>

<script>

export default {
name: 'not-found',
methods: {
setTheme() {
document.getElementsByTagName('html')[0].setAttribute('data-theme', 'dashy-docs');
},
},
mounted() {
this.setTheme();
},
};
</script>

<style scoped lang="scss">
@import '@/styles/media-queries.scss';
@import '@/styles/style-helpers.scss';
main.not-found-page {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
cursor: default;
background: #202020;
min-height: calc(99vh - var(--footer-height));
background-color: #202020;
h1.not-found-title, h2.not-found-sad-face {
font-size: 20vh;
font-family: Tahoma, monospace;
cursor: default;
color: #0c0c0c;
text-shadow: 0px 4px 4px #090909, 0 0 0 #000, 0px 2px 2px #000000;
margin: 1rem 0 0;
}
h2.not-found-sad-face {
font-size: 4rem;
margin: 0 0 1.5rem 0;
}
p {
font-family: monospace;
cursor: default;
color: #0c0c0c;
margin: 0.2rem 0;
text-shadow: 0 1px 1px #090909, 0 0 0 #000, 0 1px 1px #000000;
}
p.not-found-subtitle {
font-size: 2.8rem;
}
p.not-found-message {
font-size: 1.4rem;
font-weight: normal;
a {
color: #0c0c0c;
font-family: monospace;
}
}
a.go-home {
padding: 0.3rem 1rem;
border-radius: 3px;
font-size: 1.7rem;
cursor: pointer;
font-family: Tahoma, monospace;
color: #0c0c0c;
margin: 2rem 0 0;
text-decoration: none;
background: #db78fc;
box-shadow: 0 4px #b83ddd;
&:hover { box-shadow: 0 2px #b83ddd; }
}
::selection { background-color: #db78fc; color: #121212; }
}
</style>