Skip to content

Commit 11e0abf

Browse files
authored
🔀 Merge pull request gchq#62 from Lissy93/FEATURE_context-menu
[FEATURE] Opening methods, and context menu
2 parents b936382 + 407c4fa commit 11e0abf

16 files changed

+370
-47
lines changed

README.md

+38-13
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
[![Awesome Self-Hosted](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/awesome-selfhosted/awesome-selfhosted#personal-dashboards)
1010
![Docker Pulls](https://img.shields.io/docker/pulls/lissy93/dashy?logo=docker&style=flat-square)
1111
![Stars](https://flat.badgen.net/github/stars/lissy93/dashy?icon=github)
12-
![Current Version](https://img.shields.io/github/package-json/v/lissy93/dashy?style=flat-square&logo=azurepipelines&color=00af87)
1312
![GitHub Status](https://flat.badgen.net/github/status/lissy93/dashy?icon=github)
14-
![App Size](https://img.shields.io/github/languages/code-size/lissy93/dashy?style=flat-square)
15-
![Code Quality](https://app.codacy.com/project/badge/Grade/3be23a4a3a8a4689bd47745b201ecb74)
13+
![License MIT](https://img.shields.io/badge/License-MIT-09be48?style=flat-square&logo=opensourceinitiative)
14+
![Current Version](https://img.shields.io/github/package-json/v/lissy93/dashy?style=flat-square&logo=azurepipelines&color=00af87)
1615

1716
## Features 🌈
1817

@@ -89,8 +88,6 @@ Dashy supports 1-Click deployments on several popular cloud platforms (with more
8988
- [Deploy with Vercel](https://vercel.com/new/project?template=https://github.com/lissy93/dashy)
9089
- [Deploy with PWD](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/Lissy93/dashy/master/docker-compose.yml)
9190

92-
**[⬆️ Back to Top](#dashy)**
93-
9491
#### Basic Commands
9592

9693
The following commands can be run on Dashy. If you are using Docker, than precede each command with `docker exec -it [container-id]`, where container id can be found by running `docker ps`, e.g. `docker exec -it 92490c12baff yarn build`.
@@ -106,6 +103,8 @@ If you prefer [`NPM`](https://docs.npmjs.com), then just replace `yarn` with `np
106103
- `yarn test` - Runs tests, and outputs results
107104
- `yarn install` - Install all dependencies
108105

106+
**[⬆️ Back to Top](#dashy)**
107+
109108
---
110109

111110
## Configuring 🔧
@@ -200,10 +199,39 @@ At present, access control is handled on the frontend, and therefore in security
200199
201200
> For full monitoring documentation, see: [**Status Indicators**](./docs/status-indicators.md)
202201
203-
Dashy has an optional feature that can display a small icon ([like this](./docs/assets/status-check-demo.gif)) next to each of your running services, indicating it's current status. This is useful if you are using Dashy as your homelab's start page, as it gives you an overview of the health of each of your running services. Hovering over the indicator will show additional information, including average response time and an error message for services which are down.
202+
Dashy has an optional feature that can display a small icon next to each of your running services, indicating it's current status. This is useful if you are using Dashy as your homelab's start page, as it gives you an overview of the health of each of your running services. Hovering over the indicator will show additional information, including average response time and an error message for services which are down.
204203
205204
By default, this feature is off, but you can enable it globally by setting `appConfig.statusCheck: true`, or enable/ disable it for an individual item, with `item[n].statusCheck`. You can also specify an time interval in seconds under `appConfig.statusCheckInterval`, which will determine how often to recheck services, if this value is `0`, then status is only checked on initial page load, this is default behavior.
206205

206+
<p align="center">
207+
<img alt="Status Checks demo" src="/docs/assets/status-check-demo.gif" width="600">
208+
</p>
209+
210+
**[⬆️ Back to Top](#dashy)**
211+
212+
---
213+
214+
## Opening Methods 🖱️
215+
216+
One of the primary purposes of Dashy is to make launching commonly used apps and services as quick as possible. To aid in this, there are several different options on how items can be opened. You can configure your preference by setting the `target` property of any item, to one of the following values:
217+
- `sametab` - The app will be launched in the current tab
218+
- `newtab` - The app will be launched in a new tab
219+
- `modal` - Launch app in a resizable/ movable popup modal on the current page
220+
- `workspace` - Changes to Workspace view, and launches app
221+
222+
Even if the target is not set (or is set to `sametab`), you can still launch any given app in an alternative method: Alt + Click will open the modal, and Ctrl + Click will open in a new tab. You can also right-click on any item to see all options (as seen in the screenshot below). This custom context menu can be disabled by setting `appConfig.disableContextMenu: true`.
223+
224+
<p align="center">
225+
<img width="500" src="https://i.ibb.co/vmZdSRt/dashy-context-menu-2.png" />
226+
</p>
227+
228+
The modal and workspace views work by rendering the target application in an iframe. For this to work, the HTTP response header [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) for a given application needs to be set to `ALLOW`. If you are getting a `Refused to Connect` error then this header is set to `DENY` (or `SAMEORIGIN` and it's on a different host).
229+
230+
Here's a quick demo of the workspace view:
231+
<p align="center">
232+
<img alt="Workspace view demo" src="/docs/assets/workspace-demo.gif" width="600">
233+
</p>
234+
207235
**[⬆️ Back to Top](#dashy)**
208236

209237
---
@@ -240,18 +268,12 @@ Before you submit your pull request, please ensure the following:
240268
- Your pull request will need to be up-to-date with master, and the PR template must be filled in
241269

242270
### Repo Status
243-
![Open Issues](https://flat.badgen.net/github/open-issues/lissy93/dashy?icon=github)
244-
![Closed Issues](https://flat.badgen.net/github/closed-issues/lissy93/dashy?icon=github)
271+
245272
![Open PRs](https://flat.badgen.net/github/open-prs/lissy93/dashy?icon=github)
246273
![Total PRs](https://flat.badgen.net/github/prs/lissy93/dashy?icon=github)
247274
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/lissy93/dashy?style=flat-square)
248275
![Last Commit](https://flat.badgen.net/github/last-commit/lissy93/dashy?icon=github)
249276
![Contributors](https://flat.badgen.net/github/contributors/lissy93/dashy?icon=github)
250-
![GitHub Status](https://flat.badgen.net/github/status/lissy93/dashy?icon=github)
251-
![Stars](https://flat.badgen.net/github/stars/lissy93/dashy?icon=github)
252-
![Docker Pulls](https://img.shields.io/docker/pulls/lissy93/dashy?logo=docker&style=flat-square)
253-
![Total Lines](https://img.shields.io/tokei/lines/github/lissy93/dashy?style=flat-square)
254-
![Maintenance](https://img.shields.io/maintenance/yes/2021?style=flat-square)
255277

256278
**[⬆️ Back to Top](#dashy)**
257279

@@ -268,6 +290,9 @@ If you've found a bug, or something that isn't working as you'd expect, please r
268290
- [Ask a Question 🤷‍♀️](https://github.com/Lissy93/dashy/issues/new?assignees=Lissy93&labels=%F0%9F%A4%B7%E2%80%8D%E2%99%82%EF%B8%8F+Question&template=question------.md&title=%5BQUESTION%5D)
269291
- [Share Feedback 🌈](https://github.com/Lissy93/dashy/issues/new?assignees=&labels=%F0%9F%8C%88+Feedback&template=share-feedback---.md&title=%5BFEEDBACK%5D)
270292

293+
[**Issue Status**](https://isitmaintained.com/project/lissy93/dashy) ![Resolution Time](http://isitmaintained.com/badge/resolution/lissy93/dashy.svg) ![Open Issues](http://isitmaintained.com/badge/open/lissy93/dashy.svg) ![Closed Issues](https://badgen.net/github/closed-issues/lissy93/dashy)
294+
295+
271296
For more general questions about any of the technologies used, [StackOverflow](https://stackoverflow.com/questions/) may be more helpful first port of info
272297

273298
If you need to get in touch securely with the author (me, Alicia Sykes), drop me a message at:

docs/assets/workspace-demo.gif

2.79 MB
Loading

docs/configuring.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,17 @@ All fields are optional, unless otherwise stated.
6161
**`enableFontAwesome`** | `boolean` | _Optional_ | Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
6262
**`fontAwesomeKey`** | `string` | _Optional_ | If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`)
6363
**`faviconApi`** | `string` | _Optional_ | Which service to use to resolve favicons. Set to `local` to do this locally, without using an API. Available options are: `local`, `faviconkit`, `google`, `clearbit`, `webmasterapi` and `allesedv`. Defaults to `faviconkit`. See [Icons](/docs/icons.md#favicons) for more info
64+
**`auth`** | `array` | _Optional_ | An array of objects containing usernames and hashed passwords. If this is not provided, then authentication will be off by default, and you will not need any credentials to access the app. Note authentication is done on the client side, and so if your instance of Dashy is exposed to the internet, it is recommend to configure your web server to handle this. See [`auth`](#appconfigauth-optional)
6465
**`layout`** | `string` | _Optional_ | App layout, either `horizontal`, `vertical`, `auto` or `sidebar`. Defaults to `auto`. This specifies the layout and direction of how sections are positioned on the home screen. This can also be modified from the UI.
6566
**`iconSize`** | `string` | _Optional_ | The size of link items / icons. Can be either `small`, `medium,` or `large`. Defaults to `medium`. This can also be set directly from the UI.
6667
**`theme`** | `string` | _Optional_ | The default theme for first load (you can change this later from the UI)
6768
**`cssThemes`** | `string[]` | _Optional_ | An array of custom theme names which can be used in the theme switcher dropdown
6869
**`externalStyleSheet`** | `string` or `string[]` | _Optional_ | Either a URL to an external stylesheet or an array or URLs, which can be applied as themes within the UI
6970
**`customCss`** | `string` | _Optional_ | Raw CSS that will be applied to the page. This can also be set from the UI. Please minify it first.
7071
**`showSplashScreen`** | `boolean` | _Optional_ | Should display a splash screen while the app is loading. Defaults to false, except on first load
71-
**`auth`** | `array` | _Optional_ | An array of objects containing usernames and hashed passwords. If this is not provided, then authentication will be off by default, and you will not need any credentials to access the app. Note authentication is done on the client side, and so if your instance of Dashy is exposed to the internet, it is recommend to configure your web server to handle this. See [`auth`](#appconfigauth-optional)
7272
**`allowConfigEdit`** | `boolean` | _Optional_ | Should prevent / allow the user to write configuration changes to the conf.yml from the UI. When set to `false`, the user can only apply changes locally using the config editor within the app, whereas if set to `true` then changes can be written to disk directly through the UI. Defaults to `true`. Note that if authentication is enabled, the user must be of type `admin` in order to apply changes globally.
7373
**`disableServiceWorker`** | `boolean` | _Optional_ | Service workers cache web applications to improve load times and offer basic offline functionality, and are enabled by default in Dashy. The service worker can sometimes cause older content to be cached, requiring the app to be hard-refreshed. If you do not want SW functionality, or are having issues with caching, set this property to `true` to disable all service workers.
74+
**`disableContextMenu`** | `boolean` | _Optional_ | If set to `true`, the custom right-click context menu will be disabled. Defaults to `false`.
7475

7576
**[⬆️ Back to Top](#configuring)**
7677

@@ -103,7 +104,7 @@ All fields are optional, unless otherwise stated.
103104
**`description`** | `string` | _Optional_ | Additional info about an item, which is shown in the tooltip on hover, or visible on large tiles
104105
**`url`** | `string` | Required | The URL / location of web address for when the item is clicked
105106
**`icon`** | `string` | _Optional_ | The icon for a given item. Can be a font-awesome icon, favicon, remote URL or local URL. See [`item.icon`](#sectionicon-and-sectionitemicon)
106-
**`target`** | `string` | _Optional_ | The opening method for when the item is clicked, either `newtab`, `sametab` or `iframe`. Where `newtab` will open the link in a new tab, `sametab` will open it in the current tab, and `iframe` will open a pop-up modal with the content displayed within that iframe. Note that for the iframe to load, you must have set the CORS headers to either allow `*` ot allow the domain that you are hosting Dashy on, for some websites and self-hosted services, this is already set.
107+
**`target`** | `string` | _Optional_ | The opening method for when the item is clicked, either `newtab`, `sametab`, `modal` or `workspace`. Where `newtab` will open the link in a new tab, `sametab` will open it in the current tab, and `modal` will open a pop-up modal with the content displayed within that iframe. Note that for the iframe to load, you must have set the CORS headers to either allow `*` ot allow the domain that you are hosting Dashy on, for some websites and self-hosted services, this is already set.
107108
**`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping the URL associated with the current service, and display its status as a dot next to the item. The value here will override `appConfig.statusCheck` so you can turn off or on checks for a given service. Defaults to `appConfig.statusCheck`, falls back to `false`
108109
**`color`** | `string` | _Optional_ | An optional color for the text and font-awesome icon to be displayed in. Note that this will override the current theme and so may not display well
109110
**`backgroundColor`** | `string` | _Optional_ | An optional background fill color for the that given item. Again, this will override the current theme and so might not display well against the background

docs/theming.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ You can target specific elements on the UI with these variables. All are optiona
120120
- `--status-check-tooltip-color` - Text color for the status check tooltips. Defaults to `--primary`
121121
- `--code-editor-color` - Text color used within raw code editors. Defaults to `--black`
122122
- `--code-editor-background` - Background color for raw code editors. Defaults to `--white`
123-
124-
123+
- `--context-menu-color` - Text color for right-click context menu over items. Defaults to `--primary`
124+
- `--context-menu-background` - Background color of right-click context menu. Defaults to `--background`
125+
- `--context-menu-secondary-color` - Border and outline color for context menu. Defaults to `--background-darker`
125126

126127
#### Non-Color Variables
127128
- `--outline-color` - Used to outline focused or selected elements

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Dashy",
3-
"version": "1.2.5",
3+
"version": "1.3.5",
44
"license": "MIT",
55
"main": "server",
66
"scripts": {
@@ -86,4 +86,4 @@
8686
"> 1%",
8787
"last 2 versions"
8888
]
89-
}
89+
}
Loading

src/components/LinkItems/Collapsable.vue

-5
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ export default {
4242
components: {
4343
Icon,
4444
},
45-
data() {
46-
return {
47-
isOpen: !this.collapsed,
48-
};
49-
},
5045
methods: {
5146
/* Check that row & column span is valid, and not over the max */
5247
checkSpanNum(span, classPrefix) {
+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<template>
2+
<transition name="slide">
3+
<div class="context-menu" v-if="show && menuEnabled"
4+
:style="posX && posY ? `top:${posY}px;left:${posX}px;` : ''">
5+
<ul>
6+
<li @click="launch('sametab')">
7+
<SameTabOpenIcon />
8+
<span>Open in Current Tab</span>
9+
</li>
10+
<li @click="launch('newtab')">
11+
<NewTabOpenIcon />
12+
<span>Open in New Tab</span>
13+
</li>
14+
<li @click="launch('modal')">
15+
<IframeOpenIcon />
16+
<span>Open in Pop-Up Modal</span>
17+
</li>
18+
<li @click="launch('workspace')">
19+
<WorkspaceOpenIcon />
20+
<span>Open in Workspace View</span>
21+
</li>
22+
</ul>
23+
</div>
24+
</transition>
25+
</template>
26+
27+
<script>
28+
// Import icons for each element
29+
import SameTabOpenIcon from '@/assets/interface-icons/open-current-tab.svg';
30+
import NewTabOpenIcon from '@/assets/interface-icons/open-new-tab.svg';
31+
import IframeOpenIcon from '@/assets/interface-icons/open-iframe.svg';
32+
import WorkspaceOpenIcon from '@/assets/interface-icons/open-workspace.svg';
33+
34+
export default {
35+
name: 'ContextMenu',
36+
inject: ['config'],
37+
components: {
38+
SameTabOpenIcon,
39+
NewTabOpenIcon,
40+
IframeOpenIcon,
41+
WorkspaceOpenIcon,
42+
},
43+
props: {
44+
posX: Number, // The X coordinate for positioning
45+
posY: Number, // The Y coordinate for positioning
46+
show: Boolean, // Should show or hide the menu
47+
},
48+
data() {
49+
return {
50+
menuEnabled: !this.isMenuDisabled(), // Specifies if the context menu should be used
51+
};
52+
},
53+
methods: {
54+
/* Called on item click, emits an event up to Item */
55+
/* in order to launch the current app to a given target */
56+
launch(target) {
57+
this.$emit('contextItemClick', target);
58+
},
59+
/* Checks if the user as disabled context menu in config */
60+
isMenuDisabled() {
61+
if (this.config && this.config.appConfig) {
62+
return !!this.config.appConfig.disableContextMenu;
63+
}
64+
return false;
65+
},
66+
},
67+
};
68+
</script>
69+
70+
<style lang="scss">
71+
72+
div.context-menu {
73+
position: absolute;
74+
margin: 0;
75+
padding: 0;
76+
z-index: 8;
77+
background: var(--context-menu-background);
78+
color: var(--context-menu-color);
79+
border: 1px solid var(--context-menu-secondary-color);
80+
border-radius: var(--curve-factor);
81+
box-shadow: var(--context-menu-shadow);
82+
opacity: 0.98;
83+
84+
ul {
85+
list-style-type: none;
86+
margin: 0;
87+
padding: 0;
88+
li {
89+
cursor: pointer;
90+
padding: 0.5rem 1rem;
91+
display: flex;
92+
flex-direction: row;
93+
font-size: 1rem;
94+
&:not(:last-child) {
95+
border-bottom: 1px solid var(--context-menu-secondary-color);
96+
}
97+
&:hover {
98+
background: var(--context-menu-secondary-color);
99+
}
100+
svg {
101+
width: 1rem;
102+
margin-right: 0.5rem;
103+
path { fill: currentColor; }
104+
}
105+
}
106+
}
107+
}
108+
109+
// Define enter and leave transitions
110+
.slide-enter-active { animation: slide-in .1s; }
111+
.slide-leave-active { animation: slide-in .1s reverse; }
112+
@keyframes slide-in {
113+
0% { transform: scaleY(0.5) scaleX(0.8) translateY(-50px); }
114+
100% { transform: scaleY(1) translateY(0) translateY(0); }
115+
}
116+
</style>

0 commit comments

Comments
 (0)