mirror of https://github.com/lissy93/dashy
Search is automatically reset when an item is opened
This commit is contained in:
parent
dfdef736e2
commit
fb60e63252
|
@ -1,17 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
<head>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<title>Alicia App | My dashboard of links and things</title>
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
</head>
|
<title>Server Dashboard</title>
|
||||||
<body>
|
</head>
|
||||||
<noscript>
|
|
||||||
<strong>We're sorry but panel doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
<body>
|
||||||
</noscript>
|
<!-- Devices without JS enabled -->
|
||||||
<div id="app"></div>
|
<noscript>
|
||||||
<!-- built files will be auto injected -->
|
<strong>JavaScript is required to run this app.</strong>
|
||||||
</body>
|
</noscript>
|
||||||
</html>
|
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
<div id="app"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -17,6 +17,7 @@
|
||||||
<div class="space-filler">
|
<div class="space-filler">
|
||||||
<span>hello</span>
|
<span>hello</span>
|
||||||
<span>world</span>
|
<span>world</span>
|
||||||
|
<i class="fas fa-rocket" style="color: red;"></i>
|
||||||
</div>
|
</div>
|
||||||
<KeyboardShortcutInfo />
|
<KeyboardShortcutInfo />
|
||||||
</section>
|
</section>
|
||||||
|
@ -47,7 +48,7 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('keyup', (event) => {
|
window.addEventListener('keyup', (event) => {
|
||||||
const { key } = event;
|
const { key, keyCode } = event;
|
||||||
if (/^[a-zA-Z]$/.test(key) && !document.activeElement.id) {
|
if (/^[a-zA-Z]$/.test(key) && !document.activeElement.id) {
|
||||||
try {
|
try {
|
||||||
this.input += key;
|
this.input += key;
|
||||||
|
@ -56,6 +57,8 @@ export default {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
} else if (keyCode === 27) {
|
||||||
|
this.clearFilterInput();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,13 +22,15 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #5e6474;
|
color: #5e6474;
|
||||||
|
opacity: 0.5;
|
||||||
|
background: #05070e;
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer a{
|
footer a{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-tooltip placement="bottom" effect="dark" :content="description" :disabled="!description">
|
<el-tooltip placement="bottom" effect="dark" :content="description" :disabled="!description">
|
||||||
<a :href="url" :class="`item ${!icon && !svg? 'short': ''}`"
|
<a :href="url" :class="`item ${!icon? 'short': ''}`" v-on:click="$emit('itemClicked')"
|
||||||
tabindex="0" target="_blank" rel="noopener noreferrer">
|
tabindex="0" target="_blank" rel="noopener noreferrer">
|
||||||
<div class="tile-title" :id="`tile-${id}`">
|
<div class="tile-title" :id="`tile-${id}`">
|
||||||
<span class="text">{{ title }}</span>
|
<span class="text">{{ title }}</span>
|
||||||
|
@ -50,6 +50,9 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
itemOpened() {
|
||||||
|
this.$emit('itemClicked');
|
||||||
|
},
|
||||||
isUrl(str) {
|
isUrl(str) {
|
||||||
const pattern = new RegExp(/(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-/]))?/);
|
const pattern = new RegExp(/(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-/]))?/);
|
||||||
return pattern.test(str);
|
return pattern.test(str);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
:icon="item.icon"
|
:icon="item.icon"
|
||||||
:iconType="item.iconType"
|
:iconType="item.iconType"
|
||||||
:svg="item.svg"
|
:svg="item.svg"
|
||||||
|
@itemClicked="$emit('itemClicked')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Collapsable>
|
</Collapsable>
|
||||||
|
|
|
@ -48,6 +48,7 @@ export default {
|
||||||
if (!shouldHide) {
|
if (!shouldHide) {
|
||||||
window.setTimeout(() => { this.shouldHide = shouldHide; }, 3000);
|
window.setTimeout(() => { this.shouldHide = shouldHide; }, 3000);
|
||||||
window.addEventListener('keyup', (ev) => {
|
window.addEventListener('keyup', (ev) => {
|
||||||
|
// User pressed the escape key. Trigger permanent dismissal of dialog
|
||||||
if (ev.keyCode === 27) this.hideWelcomeHelper();
|
if (ev.keyCode === 27) this.hideWelcomeHelper();
|
||||||
});
|
});
|
||||||
} else { // Meh, component not needed.
|
} else { // Meh, component not needed.
|
||||||
|
|
|
@ -44,6 +44,9 @@ sections:
|
||||||
icon: networking/wireguard.png
|
icon: networking/wireguard.png
|
||||||
url: https://192.168.1.1/ui/wireguard/general
|
url: https://192.168.1.1/ui/wireguard/general
|
||||||
- name: DNS Device
|
- name: DNS Device
|
||||||
|
displayData:
|
||||||
|
collapsed: false
|
||||||
|
rows: 2
|
||||||
items:
|
items:
|
||||||
- title: Pi-Hole
|
- title: Pi-Hole
|
||||||
description: DNS settings for ad & tracker blocking
|
description: DNS settings for ad & tracker blocking
|
||||||
|
@ -93,25 +96,6 @@ sections:
|
||||||
description: Data visualised on dashboards
|
description: Data visualised on dashboards
|
||||||
icon: networking/grafana.png
|
icon: networking/grafana.png
|
||||||
url: http://192.168.130.2:8091/
|
url: http://192.168.130.2:8091/
|
||||||
- name: Other Devices
|
|
||||||
items:
|
|
||||||
- title: Modem
|
|
||||||
description: ISP Router Modem Combo
|
|
||||||
icon: ''
|
|
||||||
url: http://192.168.1.5
|
|
||||||
- title: Wireless Access Point
|
|
||||||
description: View clients connected to WiFi
|
|
||||||
icon: ''
|
|
||||||
url: http://192.168.1.109/info.php
|
|
||||||
- title: Fing
|
|
||||||
description: Monitor connectivity issues, ISP quality, health checks and troubleshooting
|
|
||||||
provider: Fing
|
|
||||||
icon: ''
|
|
||||||
url: https://app.fing.com/
|
|
||||||
- title: Switch
|
|
||||||
description: Manage VLANs on Ubiquity Ethernet switch
|
|
||||||
icon: ''
|
|
||||||
url: "/"
|
|
||||||
- name: External Services
|
- name: External Services
|
||||||
items:
|
items:
|
||||||
- title: DuckDNS
|
- title: DuckDNS
|
||||||
|
@ -138,6 +122,25 @@ sections:
|
||||||
description: Broadband internet provider
|
description: Broadband internet provider
|
||||||
icon: networking/vodafone.png
|
icon: networking/vodafone.png
|
||||||
url: https://myaccount.vodafone.co.uk/
|
url: https://myaccount.vodafone.co.uk/
|
||||||
|
- name: Other Devices
|
||||||
|
items:
|
||||||
|
- title: Modem
|
||||||
|
description: ISP Router Modem Combo
|
||||||
|
icon: ''
|
||||||
|
url: http://192.168.1.5
|
||||||
|
- title: Wireless Access Point
|
||||||
|
description: View clients connected to WiFi
|
||||||
|
icon: ''
|
||||||
|
url: http://192.168.1.109/info.php
|
||||||
|
- title: Fing
|
||||||
|
description: Monitor connectivity issues, ISP quality, health checks and troubleshooting
|
||||||
|
provider: Fing
|
||||||
|
icon: ''
|
||||||
|
url: https://app.fing.com/
|
||||||
|
- title: Switch
|
||||||
|
description: Manage VLANs on Ubiquity Ethernet switch
|
||||||
|
icon: ''
|
||||||
|
url: "/"
|
||||||
- name: External Utilities
|
- name: External Utilities
|
||||||
displayData:
|
displayData:
|
||||||
collapsed: true
|
collapsed: true
|
||||||
|
|
|
@ -4,20 +4,35 @@ import Home from './views/Home.vue';
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
export default new Router({
|
const router = new Router({
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
component: Home,
|
component: Home,
|
||||||
|
meta: {
|
||||||
|
title: 'Home Page',
|
||||||
|
metaTags: [
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
content: 'A simple static homepage for you\'re server',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/about',
|
path: '/about',
|
||||||
name: 'about',
|
name: 'about',
|
||||||
// route level code-splitting
|
|
||||||
// this generates a separate chunk (about.[hash].js) for this route
|
|
||||||
// which is lazy-loaded when the route is visited.
|
|
||||||
component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
|
component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const defaultTitle = 'Speed Dial';
|
||||||
|
router.afterEach((to) => {
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
document.title = to.meta.title || defaultTitle;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="home">
|
<div class="home">
|
||||||
<Header :pageInfo="getPageInfo(pageInfo)" />
|
<Header :pageInfo="getPageInfo(pageInfo)" />
|
||||||
<FilterTile @user-is-searchin="searching" class="filter-container" />
|
<FilterTile @user-is-searchin="searching" class="filter-container" ref="filterComp" />
|
||||||
<div class="item-group-container">
|
<div class="item-group-container">
|
||||||
<ItemGroup
|
<ItemGroup
|
||||||
v-for="(section, index) in sections"
|
v-for="(section, index) in sections"
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
:displayData="getDisplayData(section)"
|
:displayData="getDisplayData(section)"
|
||||||
:groupId="`section-${index}`"
|
:groupId="`section-${index}`"
|
||||||
:items="filterTiles(section.items)"
|
:items="filterTiles(section.items)"
|
||||||
|
@itemClicked="finishedSearching()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,6 +36,9 @@ export default {
|
||||||
searchTile: '',
|
searchTile: '',
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
|
finishedSearching() {
|
||||||
|
this.$refs.filterComp.clearFilterInput();
|
||||||
|
},
|
||||||
/* Returns true if the user is currently searching */
|
/* Returns true if the user is currently searching */
|
||||||
searching(searchTile) {
|
searching(searchTile) {
|
||||||
this.searchTile = searchTile;
|
this.searchTile = searchTile;
|
||||||
|
@ -74,6 +78,11 @@ export default {
|
||||||
return defaults;
|
return defaults;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
const fontAwesomeScript = document.createElement('script');
|
||||||
|
fontAwesomeScript.setAttribute('src', 'https://kit.fontawesome.com/def7c3ce4c.js');
|
||||||
|
document.head.appendChild(fontAwesomeScript);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue