🔀 Merge pull request #273 from Lissy93/REFACTOR/new-initial-config

[REFACTOR] Fix Firefox icon, new Glow theme, bug fixes, refactors, and more
This commit is contained in:
Alicia Sykes 2021-10-15 23:12:57 +01:00 committed by GitHub
commit 1469e4b715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1698 additions and 936 deletions

View File

@ -1,5 +1,14 @@
# Changelog
## ⚡️ 1.8.7 - Bug Fixes and Improvements [PR #273](https://github.com/Lissy93/dashy/pull/273)
- Clean URLs without the hash, now using history-mode routing
- New initial main example conf.yml
- Minor UI style updates and fixes
- Support for single section view
- A new theme, soft-glow
- Container security in management docs, and other things
- Bug fixes, including missing Firefox favicon and fix custom icon paths with base_url
## ⚡️ 1.8.6 - Implementation of VueX [PR: #271](https://github.com/Lissy93/dashy/pull/271)
- New state management pattern, which should lead to a more organized code base long term, and will also make building out the new UI editor significantly easier to do in a clean and reliable way

12
.github/SUPPORT.md vendored
View File

@ -1,9 +1,15 @@
# Support
To raise a bug, please **[Open a new Issue](https://github.com/Lissy93/dashy/issues/new/choose)**.
To report a potential vulnerability, follow the steps in **[Security](https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md#reporting-a-security-issue)**.
To report a potential vulnerability, please see **[Security](https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md#reporting-a-security-issue)**.
For setup and usage guides, see **[dashy.to/docs](https://dashy.to/)** or the **[GitHub](https://github.com/Lissy93/dashy)** repo.
To raise a bug, for something that's not working, **[Open a new Issue](https://github.com/Lissy93/dashy/issues/new/choose)**.
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)**.
If you'd like to help support Dashy's future development, see **[Contributing](https://github.com/Lissy93/dashy/blob/master/docs/contributing.md)**.
To get in contact with the author, email me at **`alicia at omg dot lol`** **[[PGP]](https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7)**.
-Thank you

246
.github/pr-badge.yml vendored
View File

@ -2,144 +2,144 @@
# Dynamically inserts status badges into PR description, based on certain conditions
# Checks if the required sections are missing
- label: "⚠Missing"
message: "Category"
color: "#f25265"
when: "$payload.pull_request.body.includes('Category') === false"
- label: "⚠Missing"
message: "Overview"
color: "#f25265"
when: "$payload.pull_request.body.includes('Overview') === false"
- label: "⚠Missing"
message: "Quality Checklist"
color: "#f25265"
when: "$payload.pull_request.body.includes('Code Quality Checklist') === false"
- label: "⚠Description"
message: "Incomplete"
color: "#f25265"
when: "$payload.pull_request.body.length < 25"
- label: "⚠Missing"
message: "Label"
color: "#f25265"
when: "$labels.length == 0"
- label: Missing
message: Category
color: '#f25265'
when: $payload.pull_request.body.includes('Category') === false
- label: Missing
message: Overview
color: '#f25265'
when: $payload.pull_request.body.includes('Overview') === false
- label: Missing
message: Quality Checklist
color: '#f25265'
when: $payload.pull_request.body.includes('Code Quality Checklist') === false
- label: Description
message: Incomplete
color: '#f25265'
when: $payload.pull_request.body.length < 25
- label: Missing
message: Label
color: '#f25265'
when: $labels.length == 0
# Show note when task list has unfinished items
- label: "⚠Notice"
message: "Unchecked Tasks"
when: "$payload.pull_request.body.includes('- [ ] ')"
color: "#f25265"
- label: Notice
message: Unchecked Tasks
when: $payload.pull_request.body.includes('- [ ] ')
color: '#f25265'
# Show badge indicating PR status
- label: "Status"
message: "✏️ Draft"
when: "$isDraft"
color: "#ffa933"
- label: "Status"
message: "🧱 Work in Progress"
when: "$payload.pull_request.title.includes('WIP')"
color: "#29e3f4"
- label: "Status"
message: "✅ Ready"
color: "#3ef963"
when: "$labels.includes('🔀 Ready for Merge')"
- label: Status
message: ✏️ Draft
when: $isDraft
color: '#ffa933'
- label: Status
message: 🧱 Work in Progress
when: $payload.pull_request.title.includes('WIP')
color: '#29e3f4'
- label: Status
message: ✅ Ready
color: '#3ef963'
when: $labels.includes('🔀 Ready for Merge')
# Add size label based on very large or tiny PRs
- label: "PR Size"
message: "Extra Large"
color: "#f9833e"
when: "$additions > 1000"
- label: "PR Size"
message: "Large"
color: "#f4b546"
when: "$additions > 500 && $additions < 1000"
- label: "PR Size"
message: "Medium"
color: "#f3ff59"
when: "$additions > 10 && $additions < 500"
- label: "PR Size"
message: "Quick"
color: "#3eef8b"
when: "$additions < 10"
- label: PR Size
message: Extra Large
color: '#f9833e'
when: '$additions > 1000'
- label: PR Size
message: Large
color: '#f4b546'
when: '$additions > 500 && $additions < 1000'
- label: PR Size
message: Medium
color: '#f3ff59'
when: '$additions > 10 && $additions < 500'
- label: PR Size
message: Quick
color: '#3eef8b'
when: '$additions < 10'
# Show PR number, to destination and from destination
- label: "#$prNumber"
message: "$payload.pull_request.user.login /$payload.pull_request.head.ref → $payload.repository.full_name"
color: "#ab5afc"
url: "https://github.com/$slug/tree/$branchName"
- label: '#$prNumber'
message: '$payload.pull_request.user.login /$payload.pull_request.head.ref → $payload.repository.full_name'
color: '#ab5afc'
url: 'https://github.com/$slug/tree/$branchName'
# Show total code added minus deleted
- label: "New Code"
message: "Commits: $payload.pull_request.commits | Files Changed: $payload.pull_request.changed_files | Additions: $payload.pull_request.additions-$payload.pull_request.deletions"
color: "#dddd00"
- label: New Code
message: 'Commits: $payload.pull_request.commits | Files Changed: $payload.pull_request.changed_files | Additions: $payload.pull_request.additions-$payload.pull_request.deletions'
color: '#dddd00'
# Show submitting user's username and profile link
- label: 💕 Submitted by
message: "$payload.pull_request.user.login"
color: "#f73ae6"
when: "$payload.pull_request.author_association !== 'OWNER'"
url: "https://github.com/$payload.pull_request.user.login"
message: $payload.pull_request.user.login
color: '#f73ae6'
when: $payload.pull_request.author_association !== 'OWNER'
url: 'https://github.com/$payload.pull_request.user.login'
# Show a badge indicating the PR category, based on tag
- label: "Type"
message: "✨ Feature"
color: "#39b0fd"
when: "$labels.includes('✨ New Feature')"
- label: "Type"
message: "🐛 Fix"
color: "#39b0fd"
when: "$labels.includes('🦋 Bug Fix')"
- label: "Type"
message: "📕 Docs"
color: "#39b0fd"
when: "$labels.includes('📕 Docs')"
- label: "Type"
message: "🛠️ Build Changes"
color: "#39b0fd"
when: "$labels.includes('🛠️ Build Changes')"
- label: "Type"
message: "🛠️ Build Changes"
color: "#39b0fd"
when: "$labels.includes('🛠️ Build Changes')"
- label: "Type"
message: "🚚 Refactor"
color: "#39b0fd"
when: "$labels.includes('🚚 Refactor')"
- label: "Type"
message: "💄 Stylistic Changes"
color: "#39b0fd"
when: "$labels.includes('💄 Stylistic Changes')"
- label: "Type"
message: "🌟 Showcase Addition"
color: "#39b0fd"
when: "$labels.includes('💯 Showcase')"
- label: "Type"
message: "🏗️ Architecture"
color: "#39b0fd"
when: "$labels.includes('🏗️ Architectural Changes')"
- label: "Type"
message: "🤖 Auto Submission"
color: "#39b0fd"
when: "$labels.includes('🤖 Auto')"
- label: "Type"
message: "🌐 Language Update"
color: "#39b0fd"
when: "$labels.includes('🌐 Language')"
- label: Type
message: ✨ Feature
color: '#39b0fd'
when: $labels.includes('✨ New Feature')
- label: Type
message: 🐛 Fix
color: '#39b0fd'
when: $labels.includes('🦋 Bug Fix')
- label: Type
message: 📕 Docs
color: '#39b0fd'
when: $labels.includes('📕 Docs')
- label: Type
message: 🛠️ Build Changes
color: '#39b0fd'
when: $labels.includes('🛠️ Build Changes')
- label: Type
message: 🛠️ Build Changes
color: '#39b0fd'
when: $labels.includes('🛠️ Build Changes')
- label: Type
message: 🚚 Refactor
color: '#39b0fd'
when: $labels.includes('🚚 Refactor')
- label: Type
message: 💄 Stylistic Changes
color: '#39b0fd'
when: $labels.includes('💄 Stylistic Changes')
- label: Type
message: 🌟 Showcase Addition
color: '#39b0fd'
when: $labels.includes('💯 Showcase')
- label: Type
message: 🏗️ Architecture
color: '#39b0fd'
when: $labels.includes('🏗️ Architectural Changes')
- label: Type
message: 🤖 Auto Submission
color: '#39b0fd'
when: $labels.includes('🤖 Auto')
- label: Type
message: 🌐 Language Update
color: '#39b0fd'
when: $labels.includes('🌐 Language')
# Show warning, when certain tags are applied
- label: "Warning"
message: "⛔ Do Not Merge"
color: "#f25265"
when: "$labels.includes('⛔ Don't Merge')"
- label: "Warning"
message: "🚫 Merge Conflicts"
color: "#f25265"
when: "$labels.includes('🚫 Merge Conflicts')"
- label: "Warning"
message: "🕸️ Inactive"
color: "#f25265"
when: "$labels.includes('🕸️ Inactive')"
- label: "Warning"
message: "💀 Spam"
color: "#f25265"
when: "$labels.includes('💀 Spam')"
- label: Warning
message: ⛔ Do Not Merge
color: '#f25265'
when: $labels.includes("⛔ Don't Merge")
- label: Warning
message: 🚫 Merge Conflicts
color: '#f25265'
when: $labels.includes('🚫 Merge Conflicts')
- label: Warning
message: 🕸️ Inactive
color: '#f25265'
when: $labels.includes('🕸️ Inactive')
- label: Warning
message: 💀 Spam
color: '#f25265'
when: $labels.includes('💀 Spam')

View File

@ -9,6 +9,7 @@ jobs:
assign-author:
runs-on: ubuntu-latest
steps:
- name: Assign author
uses: technote-space/assign-author@v1
GITHUB_TOKEN: ${{secrets.BOT_GITHUB_TOKEN}}
- name: Assign author
uses: technote-space/assign-author@v1
with:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}

View File

@ -6,7 +6,12 @@ on:
types: [opened, reopened]
jobs:
check-user:
if: ${{ ! contains( github.event.issue.labels.*.name, 'keep-open') && github.event.comment.author_association != 'CONTRIBUTOR' }}
if: >
${{
! contains( github.event.issue.labels.*.name, '📌 Keep Open') &&
! contains( github.event.issue.labels.*.name, '🌈 Feedback') &&
github.event.comment.author_association != 'CONTRIBUTOR'
}}
runs-on: ubuntu-latest
name: Close issue opened by non-stargazer
steps:

View File

@ -49,6 +49,7 @@
- [🌎 Language Switching](#language-switching-)
- [🌳 Dashboard Info](#setting-dashboard-info-)
- **Community**
- [📊 System Requirements](#system-requirements-)
- [🙋‍♀️ Getting Help](#getting-help-%EF%B8%8F)
- [🐛 Raising Issues](#raising-issues-)
- [💖 Supporting Dashy](#supporting-dashy-)
@ -65,22 +66,22 @@
## Features 🌈
- 🔎 Instant search by name, domain and tags - just start typing + customizable keyboard shortcuts
- 🔎 Instant search by name, domain and tags + customizable hotkeys & keyboard shortcuts
- 🎨 Multiple built-in color themes, with UI color editor and support for custom CSS
- 🧸 Many options for icons, including Font-Awesome support, auto-fetching favicon, images and emojis
- 🧸 Many options for icons, including Font-Awesome, homelab icons, auto-fetching favicon, images and emojis
- 🚦 Service status feature for each of your apps / links, for basic availability and uptime monitoring
- 💂 Optional authentication with multi-user support, configurable privileges and SSO support
- ☁ Optional encrypted cloud backup and restore feature available
- 💂 Optional authentication with multi-user access, configurable privileges and SSO support
- 🌎 Multi-language support, with more languages being added regularly
- ☁ Optional encrypted off-site cloud backup and restore feature available
- 💼 A workspace view, for easily switching between multiple apps at once
- 🛩️ A minimal view, for use as a fast-loading browser startpage
- 🖱️ Choose how to launch apps, either new tab, same tab, a pop-up modal or in the workspace view
- 🌎 Multi-language support, with more languages being added regularly
- 📏 Customizable layout, sizes, text, component visibility, sort order, behavior etc
- 🖼️ Option for full-screen background image, custom nav-bar links, html footer, title, and more
- 🖼️ Option for full-screen background image, custom nav-bar links, html footer, title, etc
- 🚀 Easy to setup with Docker, or on bare metal, or with 1-Click cloud deployment
- ⚙️ Easy single-file YAML-based configuration, with option to configure app directly through the UI
- 🤏 Small bundle size, fully responsive UI and PWA makes the app easy to use on any device
- ⚙️ Easy single-file YAML-based configuration, and option to configure app through the UI
- ✨ Under active development with improvements and new features added regularly
- 🤏 Small bundle size, fully responsive UI and PWA for basic offline access
- 🆓 100% free and open source
- 🔐 Strong focus on privacy
- 🌈 Plus lots more...
@ -480,6 +481,21 @@ pageInfo:
---
## System Requirements 📊
The hardware requirements vary depending on where and how you are running Dashy. Generally speaking, on a bare metal system or Docker container, 1GB of memory should be more than enough, and depending on weather you are using your own assets, then 1GB of disk space should be sufficient.
If you are using one of the 1-click cloud deployment methods, serving the app through a CDN or using a static hosting provider, then there are no specific requirements, as the built app is just a series of static JS files, and so is very light-weight.
Dashy also wells run on low-powered ARM-based single board computers, such as a Raspberry Pi (tested on Pi 3)
**Browser Support**
![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![IE](https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png)
--- | --- | --- | --- | --- |
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ |
---
## Getting Help 🙋‍♀️
> For general discussions, check out the **[Discussions Board](https://github.com/Lissy93/dashy/discussions)**
@ -562,7 +578,9 @@ Dashy was made possible thanks to the following packages and components. For mor
> For full development documentation, see: [**Developing**](./docs/developing.md)
[![Open Project in VS Code](https://img.shields.io/badge/Open_in-VS_Code-863cfc?style=for-the-badge&logo=visualstudiocode)](https://open.vscode.dev/Lissy93/Dashy)
[![Open Project in VS Code](https://img.shields.io/badge/Open_in-VS_Code-863cfc?style=flat-square&logo=visualstudiocode)](https://open.vscode.dev/Lissy93/Dashy)
[![Open in GitPod](https://img.shields.io/badge/Open_in-GitPod-ffae33?style=flat-square&logo=gitpod)](https://gitpod.io/#github.com/lissy93/dashy.git)
[![Open in GitHub Code Spaces](https://img.shields.io/badge/Open_in-Code%20Spaces-131313?style=flat-square&logo=github)](https://github.dev/Lissy93/dashy)
Before getting started, you'll need [Git](https://git-scm.com/downloads), [Node](https://nodejs.org/en/download/) and optionally [Yarn](https://yarnpkg.com/) (run `npm i -g yarn`) installed.

View File

@ -66,9 +66,14 @@ Sponsoring will give you several perks, from $1 / £0.70 per month, as well as a
<summary>You can also send a one-off small contribution using crypto</summary>
<p>
[![Donate with BTC](https://en.cryptobadges.io/badge/big/3853bSxupMjvxEYfwGDGAaLZhTKxB2vEVC)](https://en.cryptobadges.io/donate/3853bSxupMjvxEYfwGDGAaLZhTKxB2vEVC)[![Donate with Ethereum](https://en.cryptobadges.io/badge/big/0x0fc98cBf8bea932B4470C46C0FbE1ed1f6765017)](https://en.cryptobadges.io/donate/0x0fc98cBf8bea932B4470C46C0FbE1ed1f6765017)
- **BTC**: `3853bSxupMjvxEYfwGDGAaLZhTKxB2vEVC`
- **ETH**: `0x0fc98cBf8bea932B4470C46C0FbE1ed1f6765017` / `aliciasykes.eth`
- **XMR**: `471KZdxb6N63aABR4WYwMRjTVkc1p1x7wGsUTEF7AMYzL8L94A5pCuYWkosgJQ5Ze8Y2PscVCGZFJa3hDPg6MaDq47GUm8r`
- **LTC**: `MAuck6Ea1qaNihwKfXutkR1R6BorMth86H`
- **ZEC**: `t1bw1SefijsXRDQVxC9w64XsRK8hBhtQohQ`
</p>
</details>

View File

@ -242,3 +242,29 @@ surge ./dist
Once Dashy has been built, it is effectivley just a static web app. This means that it can be served up with pretty much any static host, CDN or web server. To host Dashy through a CDN, the steps are very similar to building from source: clone the project, cd into it, install dependencies, write your config file and build the app. Once build is complete you will have a `./dist` directory within Dashy's root, and this is the build application which is ready to be served up.
However without Dashy's node server, there are a couple of features that will be unavailible to you, including: Writing config changes to disk through the UI, triggering a rebuild through the UI and application status checks. Everything else will work fine.
## Requirements
### System Requirements
Dashy works well on a Raspberry Pi (tested on Pi 3 and later), but should also run well on any system.
### Docker
Initial app build causes a spike in resource usage, but once the built app is running it is fairly steady. For this reason, Dashy works best with a minimum of 1GB of memory, and 1GB of disk space.
### Bare Metal
Minimum 526mb mem, 2GB disk space,
### CDN / Cloud Deploy
No specific requirements. The built application alone (without the Node server) is very light-weight, and can be handled smoothly by pretty much any CDN or cloud deployment service (see [this list](/docs/deployment.md#deploy-to-cloud-service) or natively supported cloud providers).
If you're using your own icons, or other assets, additional disk space will be required for those resources.
### Browser Support
JavaScript is required to run Dashy.
In terms of browser support, pretty much any browser released since 2018 should render content just fine. However, for Internet Explorer, only IE11+ is supported, yet performance here is still not optimal. The recommended browser is either a Chromium-based / Webkit browser (Chrome, Brave, Vivaldi, Edge, Yandex, etc), or Firefox or one of it's forks (FF-ESR, Tor, LibreWolf, etc). Recent versions of Safari and Opera are also supported, but with limited continuous testing.
<p align="center"><img width="500" src="https://i.ibb.co/pjnmbw9/browser-compatibility.png" /></p>

View File

@ -145,8 +145,10 @@ When you submit your PR, include the required info, by filling out the PR templa
## Resources for Beginners
New to Web Development? Glad you're here! Dashy is a pretty simple app, so it should make a good candidate for your first PR. Presuming that you already have a basic knowledge of JavaScript, the following articles should point you in the right direction for getting up to speed with the technologies used in this project:
- [Open Source for Beginners](https://opensource.guide/how-to-contribute/)
- [Introduction to Vue.js](https://v3.vuejs.org/guide/introduction.html)
- [Vue.js Walkthrough](https://www.taniarascia.com/getting-started-with-vue/)
- [ES6 Features](https://github.com/lukehoban/es6features)
- [Definitive guide to SCSS](https://blog.logrocket.com/the-definitive-guide-to-scss/)
- [Complete beginners guide to Docker](https://docker-curriculum.com/)
- [Docker Classroom - Interactive Tutorials](https://training.play-with-docker.com/)

View File

@ -1,27 +1,67 @@
# Management
## Providing Assets
Although not essential, you will most likely want to provide several assets to Dashy. All web assets can be found in the `/public` directory.
_The following article explains aspects of app management, and is useful to know for when self-hosting. It covers everything from keeping the app up-to-date, secure, backed up, to other topics like auto-starting, monitoring, log management, web server configuration and using custom environments. Most of it is aimed at running the Dashy (or any other app) in a container, but some of it also applies to bare metal setups too. It's like a top-15 list of need-to-know knowledge for self-hosting._
For example:
- `./public/conf.yml` - As mentioned, this is your main application config file
- `./public/item-icons` - If you're using your own icons, you can choose to store them locally for better load time, and this is the directory to put them in. You can also use sub-folders here to keep things organized
- Also within `./public` you'll find standard website assets, including `favicon.ico`, `manifest.json`, `robots.txt`, etc. There's no need to pass these in, but you can do so if you wish
## Contents
- [Providing Assets](#providing-assets)
- [Running Commands](#running-commands)
- [Healthchecks](#healthchecks)
- [Logs and Performance](#logs-and-performance)
- [Auto-Starting at Boot](#auto-starting-at-system-boot)
- [Updating](#updating)
- [Backing Up](#backing-up)
- [Scheduling](#scheduling)
- [SSL Certificates](#ssl-certificates)
- [Authentication](#authentication)
- [Managing with Compose](#managing-containers-with-docker-compose)
- [Environmental Variables](#passing-in-environmental-variables)
- [Securing Containers](#container-security)
- [Web Server Configuration](#web-server-configuration)
- [Running a Modified Apps](#running-a-modified-version-of-the-app)
---
## Providing Assets
Although not essential, you will most likely want to provide several assets to your running app.
This is easy to do using [Docker Volumes](https://docs.docker.com/storage/volumes/), which lets you share a file or directory between your host system, and the container. Volumes are specified in the Docker run command, or Docker compose file, using the `--volume` or `-v` flags. The value of which consists of the path to the file / directory on your host system, followed by the destination path within the container. Fields are separated by a colon (`:`), and must be in the correct order. For example: `-v ~/alicia/my-local-conf.yml:/app/public/conf.yml`
In Dashy, commonly configured resources include:
- `./public/conf.yml` - Your main application config file
- `./public/item-icons` - A directory containing your own icons. This allows for offline access, and better performance than fetching from a CDN
- Also within `./public` you'll find standard website assets, including `favicon.ico`, `manifest.json`, `robots.txt`, etc. There's no need to pass these in, but you can do so if you wish
- `/src/styles/user-defined-themes.scss` - A stylesheet for applying custom CSS to your app. You can also write your own themes here.
**[⬆️ Back to Top](#management)**
---
## Running Commands
The project has a few commands that can be used for various tasks, you can find a list of these either in the [Developing Docs](/docs/developing.md#project-commands), or by looking at the [`package.json`](https://github.com/Lissy93/dashy/blob/master/package.json#L5). These can be used by running `yarn [command-name]`.
But if you're using Docker, then you'll need to execute them within the container. This can be done by preceding each command with `docker exec -it [container-id]`, where container ID can be found by running `docker ps`. For example `docker exec -it 26c156c467b4 yarn build`. You can also enter the container, with `docker exec -it [container-id] /bin/ash`, and navigate around it with normal Linux commands.
If you're using Docker, then you'll need to execute them within the container. This can be done by preceding each command with `docker exec -it [container-id]`, where container ID can be found by running `docker ps`. For example `docker exec -it 26c156c467b4 yarn build`. You can also enter the container, with `docker exec -it [container-id] /bin/ash`, and navigate around it with normal Linux commands.
**[⬆️ Back to Top](#management)**
---
## Healthchecks
Healthchecks are configured to periodically check that Dashy is up and running correctly on the specified port. By default, the health script is called every 5 minutes, but this can be modified with the `--health-interval` option. You can check the current container health with: `docker inspect --format "{{json .State.Health }}" [container-id]`, and a summary of health status will show up under `docker ps`. You can also manually request the current application status by running `docker exec -it [container-id] yarn health-check`. You can disable healthchecks altogether by adding the `--no-healthcheck` flag to your Docker run command.
To restart unhealthy containers automatically, check out [Autoheal](https://hub.docker.com/r/willfarrell/autoheal/). This image watches for unhealthy containers, and automatically triggers a restart. This is a stand in for Docker's `--exit-on-unhealthy` that was proposed, but [not merged](https://github.com/moby/moby/pull/22719).
To restart unhealthy containers automatically, check out [Autoheal](https://hub.docker.com/r/willfarrell/autoheal/). This image watches for unhealthy containers, and automatically triggers a restart. (This is a stand in for Docker's `--exit-on-unhealthy` that was proposed, but [not merged](https://github.com/moby/moby/pull/22719)).
```
docker run -d \
--name autoheal \
--restart=always \
-e AUTOHEAL_CONTAINER_LABEL=all \
-v /var/run/docker.sock:/var/run/docker.sock \
willfarrell/autoheal
```
**[⬆️ Back to Top](#management)**
---
## Logs and Performance
#### Container Logs
@ -36,6 +76,10 @@ You can also view logs, resource usage and other info as well as manage your ent
#### Advanced Logging and Monitoring
Docker supports using [Prometheus](https://prometheus.io/) to collect logs, which can then be visualized using a platform like [Grafana](https://grafana.com/). For more info, see [this guide](https://docs.docker.com/config/daemon/prometheus/). If you need to route your logs to a remote syslog, then consider using [logspout](https://github.com/gliderlabs/logspout). For enterprise-grade instances, there are managed services, that make monitoring container logs and metrics very easy, such as [Sematext](https://sematext.com/blog/docker-container-monitoring-with-sematext/) with [Logagent](https://github.com/sematext/logagent-js).
**[⬆️ Back to Top](#management)**
---
## Auto-Starting at System Boot
You can use Docker's [restart policies](https://docs.docker.com/engine/reference/run/#restart-policies---restart) to instruct the container to start after a system reboot, or restart after a crash. Just add the `--restart=always` flag to your Docker compose script or Docker run command. For more information, see the docs on [Starting Containers Automatically](https://docs.docker.com/config/containers/start-containers-automatically/).
@ -44,25 +88,6 @@ For Podman, you can use `systemd` to create a service that launches your contain
To restart the container after something within it has crashed, consider using [`docker-autoheal`](https://github.com/willfarrell/docker-autoheal) by @willfarrell, a service that monitors and restarts unhealthy containers. For more info, see the [Healthchecks](#healthchecks) section above.
## Securing
#### SSL
Enabling HTTPS with an SSL certificate is recommended if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit.
[Let's Encrypt](https://letsencrypt.org/docs/) is a global Certificate Authority, providing free SSL/TLS Domain Validation certificates in order to enable secure HTTPS access to your website. They have good browser/ OS [compatibility](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate
[ZeroSSL](https://zerossl.com/) is another popular certificate issuer, they are free for personal use, and also provide easy-to-use tools for getting things setup.
If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/).
If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) to generate your Let's Encrypt or ZeroSSL certificate, and support shared hosting servers. They also provide step-by-step tutorials on setting up your certificate on most common platforms. If you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful.
#### Authentication
Dashy has [basic authentication](/docs/authentication.md) built in, however at present this is handled on the front-end, and so where security is critical, it is recommended to use an alternative method. See [here](/docs/authentication.md#alternative-authentication-methods) for options regarding securing Dashy.
**[⬆️ Back to Top](#management)**
---
@ -95,11 +120,277 @@ docker run -d \
For more information, see the [Watchtower Docs](https://containrrr.dev/watchtower/)
### Updating Dashy from Source
1. Navigate into directory: `cd ./dashy`
2. Stop your current instance
3. Pull latest code: `git pull origin master`
4. Re-build: `yarn build`
5. Start: `yarn start`
Stop your current instance of Dashy, then navigate into the source directory. Pull down the latest code, with `git pull origin master`, then update dependencies with `yarn`, rebuild with `yarn build`, and start the server again with `yarn start`.
**[⬆️ Back to Top](#management)**
---
## Backing Up
### Backing Up Containers
You can make a backup of any running container really easily, using [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit/) and save it with [`docker export`](https://docs.docker.com/engine/reference/commandline/export/), to do so:
- First find the container ID, you can do this with `docker container ls`
- Now to create the snapshot, just run `docker commit -p [container-id] my-backup`
- Finally, to save the backup locally, run `docker save -o ~/dashy-backup.tar my-backup`
- If you want to push this to a container registry, run `docker push my-backup:latest`
Note that this will not include any data in docker volumes, and the process here is a bit different. Since these files exist on your host system, if you have an existing backup solution implemented, you can incorporate and volume files within that system.
### Backing Up Volumes
[offen/docker-volume-backup](https://github.com/offen/docker-volume-backup) is a useful tool for periodic Docker volume backups, to any S3-compatible storage provider. It's run as a light-weight Docker container, and is easy to setup, and also supports GPG-encryption, email notification, and routing away older backups.
To get started, create a docker-compose similar to the example below, and then start the container. For more info, check out their [documentation](https://github.com/offen/docker-volume-backup), which is very clear.
```yaml
version: '3'
services:
backup:
image: offen/docker-volume-backup:latest
environment:
BACKUP_CRON_EXPRESSION: "0 * * * *"
BACKUP_PRUNING_PREFIX: backup-
BACKUP_RETENTION_DAYS: 7
AWS_BUCKET_NAME: backup-bucket
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
volumes:
- data:/backup/my-app-backup:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes:
data:
```
It's worth noting that this process can also be done manually, using the following commands:
Backup:
```
docker run --rm -v some_volume:/volume -v /tmp:/backup alpine tar -cjf /backup/some_archive.tar.bz2 -C /volume ./
```
Restore:
```
docker run --rm -v some_volume:/volume -v /tmp:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/some_archive.tar.bz2"
```
### Dashy-Specific Backup
Since Dashy is open source, and freely available, providing you're configuration data is passed in as volumes, there shouldn't be any need to backup the main container. Your main config file, and any assets you're using should be kept backed up, preferably in at least two places, and you should ensure that you can easily restore from backup, if needed.
Dashy also has a built-in cloud backup feature, which is free for personal users, and will let you make and restore fully encrypted backups of your config directly through the UI. To learn more, see the [Cloud Backup Docs](/docs/backup-restore.md)
**[⬆️ Back to Top](#management)**
---
## Scheduling
If you need to periodically schedule the running of a given command on Dashy (or any other container), then a useful tool for doing so it [ofelia](https://github.com/mcuadros/ofelia). This runs as a Docker container and is really useful for things like backups, logging, updating, notifications, etc. Crons are specified using Go's crontab format, and a useful tool for visualizing this is [crontab.guru](https://crontab.guru/). This can also be done natively with Alpine: `docker run -it alpine ls /etc/periodic`.
I recommend combining this with [healthchecks](https://github.com/healthchecks/healthchecks) for easy monitoring of jobs, and failure notifications.
**[⬆️ Back to Top](#management)**
---
## SSL Certificates
Enabling HTTPS with an SSL certificate is recommended if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit.
[Let's Encrypt](https://letsencrypt.org/docs/) is a global Certificate Authority, providing free SSL/TLS Domain Validation certificates in order to enable secure HTTPS access to your website. They have good browser/ OS [compatibility](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate
[ZeroSSL](https://zerossl.com/) is another popular certificate issuer, they are free for personal use, and also provide easy-to-use tools for getting things setup.
If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/).
If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) to generate your Let's Encrypt or ZeroSSL certificate, and support shared hosting servers. They also provide step-by-step tutorials on setting up your certificate on most common platforms. If you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful.
**[⬆️ Back to Top](#management)**
---
## Authentication
Dashy natively supports secure authentication using KeyCloak. There is also a Simple Auth feature that doesn't require any additional setup. Setup instructions for which, and alternative auth methods, has now moved to the **[Authentication Docs](/docs/authentication.md)** page.
**[⬆️ Back to Top](#management)**
---
## Managing Containers with Docker Compose
When you have a lot of containers, it quickly becomes hard to manage with `docker run` commands. The solution to this is [docker compose](https://docs.docker.com/compose/), a handy tool for defining all a containers run settings in a single YAML file, and then spinning up that container with a single short command - `docker compose up`. A good example of which can be seen in [@abhilesh's docker compose collection](https://github.com/abhilesh/self-hosted_docker_setups).
You can use Dashy's default [`docker-compose.yml`](https://github.com/Lissy93/dashy/blob/master/docker-compose.yml) file as a template, and modify it according to your needs.
An example Docker compose, using the default base image from DockerHub, might look something like this:
```yaml
---
version: "3.8"
services:
dashy:
container_name: Dashy
image: lissy93/dashy
volumes:
- /root/my-config.yml:/app/public/conf.yml
ports:
- 4000:80
environment:
- BASE_URL=/my-dashboard
restart: unless-stopped
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
```
**[⬆️ Back to Top](#management)**
---
## Passing in Environmental Variables
With Docker, you can define environmental variables under the `environment` section of your Docker compose file. Environmental variables are used to configure high-level settings, usually before the config file has been read. For a list of all supported env vars in Dashy, see [the developing docs](/docs/developing.md#environmental-variables), or the default [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file.
A common use case, is to run Dashy under a sub-page, instead of at the root of a URL (e.g. `https://my-homelab.local/dashy` instead of `https://dashy.my-homelab.local`). In this use-case, you'd specify the `BASE_URL` variable in your compose file.
```yaml
environment:
- BASE_URL=/dashy
```
You can also do the same thing with the docker run command, using the [`--env`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) flag.
If you've got many environmental variables, you might find it useful to put them in a [`.env` file](https://docs.docker.com/compose/env-file/). Similarly, for Docker run you can use [`--env-file`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) if you'd like to pass in a file containing all your environmental variables.
**[⬆️ Back to Top](#management)**
---
## Container Security
### Keep Docker Up-To-Date
To prevent known container escape vulnerabilities, which typically end in escalating to root/administrator privileges, patching Docker Engine and Docker Machine is crucial. For more info, see the [Docker Installation Docs](https://docs.docker.com/engine/install/).
### Set Resource Quotas
Docker enables you to limit resource consumption (CPU, memory, disk) on a per-container basis. This not only enhances system performance, but also prevents a compromised container from consuming a large amount of resources, in order to disrupt service or perform malicious activities. To learn more, see the [Resource Constraints Docs](https://docs.docker.com/config/containers/resource_constraints/)
For example, to run Dashy with max of 1GB ram, and max of 50% of 1 CP core:
`docker run -d -p 8080:80 --cpus=".5" --memory="1024m" lissy93/dashy:latest`
### Don't Run as Root
Running a container with admin privileges gives it more power than it needs, and can be abused. Dashy does not need any root privileges, and Docker by default doesn't run containers as root, so providing you don't specifically type sudo, you should be all good here.
Note that if you're facing permission issues on Debian-based systems, you may need to add your user to the Docker group. First create the group: `sudo groupadd docker`, then add your (non-root) user: `sudo usermod aG docker [my-username]`, finally `newgrp docker` to refresh.
### Specify a User
One of the best ways to prevent privilege escalation attacks, is to configure the container to use an unprivileged user. This also means that any files created by the container and mounted, will be owned by the specified user (and not root), which makes things much easier.
You can specify a user, using the [`--user` param](https://docs.docker.com/engine/reference/run/#user), and should include the user ID (`UID`), which can be found by running `id -u`, and the and the group ID (`GID`), using `id -g`.
With Docker run, you specify it like:
`docker run --user 1000:1000 -p 8080:80 lissy93/dashy`
Of if you're using Docker-compose, you could use an environmental variable
```yaml
version: "3.8"
services:
dashy:
image: lissy93/dashy
user: ${CURRENT_UID}
ports: [ 4000:80 ]
```
And then to set the variable, and start the container, run: `CURRENT_UID=$(id -u):$(id -g) docker-compose up`
### Limit capabilities
Docker containers run with a subset of [Linux Kernal's Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) by default. It's good practice to drop privilege permissions that are not needed for any given container.
With Docker run, you can use the `--cap-drop` flag to remove capabilities, you can also use `--cap-drop=all` and then define just the required permissions using the `--cap-add` option. For a list of available capabilities, see the [Privilege Capabilities Docs](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).
Here's an example using docker-compose, removing privileges that are not required for Dashy to run:
```yaml
version: "3.8"
services:
dashy:
image: lissy93/dashy
ports: [ 4000:80 ]
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
- DAC_OVERRIDE
- NET_BIND_SERVICE
```
### Prevent new Privilages being Added
To prevent processes inside the container from getting additional privileges, pass in the `--security-opt=no-new-privileges:true` option to the Docker run command (see [docs](https://docs.docker.com/engine/reference/run/#security-configuration)).
Run Command:
`docker run --security-opt=no-new-privileges:true -p 8080:80 lissy93/dashy`
Docker Compose
```yaml
security_opt:
- no-new-privileges:true
```
### Disable Inter-Container Communication
By default Docker containers can talk to each other (using [`docker0` bridged network](https://docs.docker.com/config/containers/container-networking/)). If you don't need this capability, then it should be disabled. This can be done with the `--icc=false` in your run command. You can learn more about how to facilitate secure communication between containers in the [Compose Networking docs](https://docs.docker.com/compose/networking/).
### Don't Expose the Docker Daemon Socket
Docker socket `/var/run/docker.sock` is the UNIX socket that Docker is listening to. This is the primary entry point for the Docker API. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host.
You should **not** enable TCP Docker daemon socket (`-H tcp://0.0.0.0:XXX`), as doing so exposes un-encrypted and unauthenticated direct access to the Docker daemon, and if the host is connected to the internet, the daemon on your computer can be used by anyone from the public internet- which is bad. If you need TCP, you should [see the docs](https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option) to understand how to do this more securely.
Similarly, never expose `/var/run/docker.sock` to other containers as a volume, as it can be exploited.
### Use Read-Only Volumes
You can specify that a specific volume should be read-only by appending `:ro` to the `-v` switch. For example, while running Dashy, if we want our config to be writable, but keep all other assets protected, we would do:
```
docker run -d \
-p 8080:80 \
-v ~/dashy-conf.yml:/app/public/conf.yml \
-v ~/dashy-icons:/app/public/item-icons:ro \
-v ~/dashy-theme.scss:/app/src/styles/user-defined-themes.scss:ro \
lissy93/dashy:latest
```
You can also prevent a container from writing any changes to volumes on your host's disk, using the `--read-only` flag. Although, for Dashy, you will not be able to write config changes to disk, when edited through the UI with this method. You could make this work, by specifying the config directory as a temp write location, with `--tmpfs /app/public/conf.yml` - but that this will not write the volume back to your host.
### Set the Logging Level
Logging is important, as it enables you to review events in the future, and in the case of a compromise this will let get an idea of what may have happened. The default log level is `INFO`, and this is also the recommendation, use `--log-level info` to ensure this is set.
### Verify Image before Pulling
Only use trusted images, from verified/ official sources. If an app is open source, it is more likely to be safe, as anyone can verify the code. There are also tools available for scanning containers,
Unless otherwise configured, containers can communicate among each other, so running one bad image may lead to other areas of your setup being compromised. Docker images typically contain both original code, as well as up-stream packages, and even if that image has come from a trusted source, the up-stream packages it includes may not have.
### Specify the Tag
Using fixed tags (as opposed to `:latest` ) will ensure immutability, meaning the base image will not change between builds. Note that for Dashy, the app is being actively developed, new features, bug fixes and general improvements are merged each week, and if you use a fixed version you will not enjoy these benefits. So it's up to you weather you would prefer a stable and reproducible environment, or the latest features and enhancements.
### Container Security Scanning
It's helpful to be aware of any potential security issues in any of the Docker images you are using. You can run a quick scan using Snyk on any image to output known vulnerabilities using [Docker scan](https://docs.docker.com/engine/scan/), e.g: `docker scan lissy93/dashy:latest`.
A similar product is [Trivy](https://github.com/aquasecurity/trivy), which is free an open source. First install it (with your package manager), then to scan an image, just run: `trivy image lissy93/dashy:latest`
For larger systems, RedHat [Clair](https://www.redhat.com/en/topics/containers/what-is-clair) is an app for parsing image contents and reporting on any found vulnerabilities. You run it locally in a container, and configure it with YAML. It can be integrated with Red Hat Quay, to show results on a dashboard. Most of these use static analysis to find potential issues, and scan included packages for any known security vulnerabilities.
### Registry Security
Although over-kill for most users, you could run your own registry locally which would give you ultimate control over all images, see the [Deploying a Registry Docs](https://docs.docker.com/registry/deploying/) for more info. Another option is [Docker Trusted Registry](https://docker-docs.netlify.app/ee/dtr/), it's great for enterprise applications, it sits behind your firewall, running on a swarm managed by Docker Universal Control Plane, and lets you securely store and manage your Docker images, mitigating the risk of breaches from the internet.
### Security Modules
Docker supports several modules that let you write your own security profiles.
[AppArmor](https://www.apparmor.net/)is a kernel module that proactively protects the operating system and applications from external or internal threats, by enabling you to restrict programs' capabilities with per-program profiles. You can specify either a security policy by name, or by file path with the `apparmor` flag in docker run. Learn more about writing profiles, [here](https://gitlab.com/apparmor/apparmor/-/wikis/QuickProfileLanguage).
[Seccomp](https://en.wikipedia.org/wiki/Seccomp) (Secure Computing Mode) is a sandboxing facility in the Linux kernel that acts like a firewall for system calls (syscalls). It uses Berkeley Packet Filter (BPF) rules to filter syscalls and control how they are handled. These filters can significantly limit a containers access to the Docker Hosts Linux kernel - especially for simple containers/applications. It requires a Linux-based Docker host, with secomp enabled, and you can check for this by running `docker info | grep seccomp`. A great resource for learning more about this is [DockerLabs](https://training.play-with-docker.com/security-seccomp/).
**[⬆️ Back to Top](#management)**
@ -180,9 +471,19 @@ Then restart Apache, with `sudo systemctl restart apache2`
---
## Authentication
## Running a Modified Version of the App
Dashy has built-in authentication and login functionality. However, since this is handled on the client-side, if you are using Dashy in security-critical situations, it is recommended to use an alternate method for authentication, such as [Authelia](https://www.authelia.com/), a VPN or web server and firewall rules. For more info, see **[Authentication Docs](/docs/authentication.md)**.
If you'd like to make any code changes to the app, and deploy your modified version, this section briefly explains how.
The first step is to fork the project on GitHub, and clone it to your local system. Next, install the dependencies (`yarn`), and start the development server (`yarn dev`) and visit `localhost:8080` in your browser. You can then make changes to the codebase, and see the live app update in real-time. Once you've finished, running `yarn build` will build the app for production, and output the assets into `./dist` which can then be deployed using a web server, CDN or the built-in Node server with `yarn start`. For more info on all of this, take a look at the [Developing Docs](/docs/developing.md).
**[⬆️ Back to Top](#management)**
You probably want to deploy your app with Docker, and this can be done as follows:
To build and deploy locally, first build the app with: `docker build -t dashy .`, and then start the app with `docker run -p 8080:80 --name my-dashboard dashy`. Or modify the `docker-compose.yml` file, replacing `image: lissy93/dashy` with `build: .` and run `docker compose up`.
Your container should now be running, and will appear in the list when you run `docker container ls a`. If you'd like to enter the container, run `docker exec -it [container-id] /bin/ash`.
You may wish to upload your image to a container registry for easier access. Note that if you choose to do this on a public registry, please name your container something other than just 'dashy', to avoid confusion with the official image.
You can push your build image, by running: `docker push ghcr.io/OWNER/IMAGE_NAME:latest`. You will first need to authenticate, this can be done by running `echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin`, where `CR_PAT` is an environmental variable containing a token generated from your GitHub account. For more info, see the [Container Registry Docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry).
**[⬆️ Back to Top](#management)**

View File

@ -19,14 +19,15 @@ To pull the latest image, and build and start the app run:
```
docker run -d \
-p 8080:80 \
-v ~/my-conf.yml:/app/public/conf.yml \
--name my-dashboard \
--restart=always \
lissy93/dashy:latest
```
For a full list of available options, then see [Dashy with Docker](https://github.com/Lissy93/dashy/blob/master/docs/deployment.md#deploy-with-docker) Docs. If you'd prefer to use Docker Compose, then see [Dashy with Docker Compose](https://github.com/Lissy93/dashy/blob/master/docs/deployment.md#using-docker-compose) Docs.
Either replace the -v path to point to your config file, or leave it out. For a full list of available options, then see [Dashy with Docker](https://github.com/Lissy93/dashy/blob/master/docs/deployment.md#deploy-with-docker) Docs. If you'd prefer to use Docker Compose, then see [Dashy with Docker Compose](https://github.com/Lissy93/dashy/blob/master/docs/deployment.md#using-docker-compose) Docs.
Your dashboard should now be up and running at `http://localhost:8080` (or your servers IP address/ domain, and the port that you chose). The first build will may take a few minutes
Your dashboard should now be up and running at `http://localhost:8080` (or your servers IP address/ domain, and the port that you chose). The first time you build, it may take a few minutes.
---

View File

@ -32,7 +32,8 @@
### Dashy Live
> By [@Lissy93](https://github.com/lissy93)
> A dashboard I made to manage all project development links from one place
> A dashboard I made to manage all project development links from one place. View demo at [live.dashy.to](https://live.dashy.to/).
![screenshot-dashy-live](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/10-dashy-live.png)

View File

@ -138,6 +138,12 @@ Please acknowledge the difference between errors and warnings before raising an
---
## Docker Login Fails on Ubuntu
Run `sudo apt install gnupg2 pass && gpg2 -k`
---
## Status Checks Failing
If you're using status checks, and despite a given service being online, the check is displaying an error, there are a couple of things you can look at:

View File

@ -1,6 +1,6 @@
{
"name": "Dashy",
"version": "1.8.6",
"version": "1.8.7",
"license": "MIT",
"main": "server",
"scripts": {
@ -16,12 +16,13 @@
"dependency-audit": "npx improved-yarn-audit --ignore-dev-deps"
},
"dependencies": {
"@sentry/tracing": "^6.10.0",
"@sentry/vue": "^6.10.0",
"ajv": "^8.6.2",
"@sentry/tracing": "^6.13.1",
"@sentry/vue": "^6.13.1",
"ajv": "^8.6.3",
"axios": "^0.21.4",
"body-parser": "^1.19.0",
"connect": "^3.7.0",
"connect-history-api-fallback": "^1.6.0",
"crypto-js": "^4.1.1",
"js-yaml": "^4.1.0",
"keycloak-js": "^15.0.2",
@ -29,15 +30,15 @@
"remedial": "^1.0.8",
"rsup-progress": "^2.0.4",
"serve-static": "^1.14.1",
"simple-icons": "^5.12.0",
"simple-icons": "^5.14.0",
"v-jsoneditor": "^1.4.2",
"v-tooltip": "^2.1.3",
"vue": "^2.6.10",
"vue-i18n": "^8.25.0",
"vue-i18n": "^8.25.1",
"vue-js-modal": "^2.0.0-rc.6",
"vue-material-tabs": "0.1.5",
"vue-router": "^3.0.3",
"vue-select": "^3.12.1",
"vue-select": "^3.13.0",
"vue-swatches": "^2.1.1",
"vue-toasted": "^1.1.28",
"vuex": "^3.6.2"

View File

@ -1,33 +1,47 @@
---
# Page meta info, like heading, footer text and nav links
pageInfo:
title: Dashy
description: Welcome to your new dashboard!
navLinks:
- title: Home
path: /
- title: About
path: /about
- title: Source Code
- title: GitHub
path: https://github.com/Lissy93/dashy
- title: Documentation
path: https://dashy.to/docs
# Optional app settings and configuration
appConfig:
theme: colorful
fontAwesomeKey: 0821c65656
# Main content - An array of sections, each containing an array of items
sections:
- name: Getting Started
icon: fas fa-rocket
items:
- title: Source
description: Source code and documentation on GitHub
icon: fab fa-github
url: https://github.com/Lissy93/dashy
- title: Issues
description: View currently open issues, or raise a new one
icon: fas fa-bug
url: https://github.com/Lissy93/dashy/issues
- title: Demo 1
description: 'Live Demo #1'
icon: far fa-rocket
url: https://dashy-demo-1.netlify.app
- title: Demo 2
description: 'Live Demo #2'
icon: fad fa-planet-ringed
url: https://dashy-demo-2.netlify.app
- title: Dashy Live
description: Development a project management links for Dashy
icon: https://i.ibb.co/qWWpD0v/astro-dab-128.png
url: https://live.dashy.to/
target: newtab
- title: GitHub
description: Source Code, Issues and Pull Requests
url: https://github.com/lissy93/dashy
icon: favicon
- title: Docs
description: Configuring & Usage Documentation
provider: Dashy.to
icon: far fa-book
url: https://dashy.to/docs
- title: Showcase
description: See how others are using Dashy
url: https://github.com/Lissy93/dashy/blob/master/docs/showcase.md
icon: far fa-grin-hearts
- title: Config Guide
description: See full list of configuration options
url: https://github.com/Lissy93/dashy/blob/master/docs/configuring.md
icon: fas fa-wrench
- title: Support
description: Get help with Dashy, raise a bug, or get in contact
url: https://github.com/Lissy93/dashy/blob/master/.github/SUPPORT.md
icon: far fa-hands-helping

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B

View File

@ -47,6 +47,9 @@
color: #0c0c0c;
text-shadow: 0px 4px 4px #090909, 0 0 0 #000, 0px 2px 2px #000000;
}
@media (max-width: 780px) {
.loading-placeholder h1 { font-size: 12vh !important; }
}
#app .loading-placeholder p {
font-size: 2rem;
font-family: monospace;

View File

@ -12,6 +12,7 @@ const util = require('util');
const dns = require('dns');
const os = require('os');
const bodyParser = require('body-parser');
const history = require('connect-history-api-fallback');
/* Kick of some basic checks */
require('./services/update-checker'); // Checks if there are any updates available, prints message
@ -56,6 +57,7 @@ const method = (m, mw) => (req, res, next) => (req.method === m ? mw(req, res, n
try {
connect()
.use(history())
.use(bodyParser.json())
// Serves up the main built application to the root
.use(serveStatic(`${__dirname}/dist`))

View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-alt-left" class="svg-inline--fa fa-arrow-alt-left fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M448 208v96c0 13.3-10.7 24-24 24H224v103.8c0 21.4-25.8 32.1-41 17L7 273c-9.4-9.4-9.4-24.6 0-34L183 63.3c15.1-15.1 41-4.4 41 17V184h200c13.3 0 24 10.7 24 24z"></path></svg>

After

Width:  |  Height:  |  Size: 404 B

View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bars" class="svg-inline--fa fa-bars fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path></svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -0,0 +1,104 @@
{
"home": {
"no-results": "Nay Search Results",
"no-data": "Nay Data Configured"
},
"search": {
"search-placeholder": "Start typin' t' filter",
"enter-to-search-web": "Press enter t' search th' web"
},
"login": {
"remember-me-label": "Remember me fer",
"error-missing-username": "Missin' Username",
"error-missing-password": "Missin' Password",
"success-message": "Loggin' in...",
"already-logged-in-text": "ye're logged in as",
"proceed-to-dashboard": "Proceed t' Dashboard",
"log-out-button": "Logout Ye All",
"proceed-guest-button": "Proceed as Ye Guest"
},
"config": {
"main-tab": "Ya Main Menu",
"heading": "Ye Configuration Options",
"download-config-button": "Download Config",
"reset-settings-button": "Reset Ship Settin's",
"change-language-button": "Change Ye Language",
"cloud-sync-button": "Enable Ship Sync",
"app-info-button": "Th' Ship Info",
"backup-note": "It be recommend t' make a backup o' yer configuration before makin' changes.",
"reset-config-msg-l1": "This will remove all user settin's from local storage, but won't effect yer 'conf.yml' file.",
"reset-config-msg-l2": "ye should first backup any changes ye've made locally, if ye want t' use them in th' future.",
"reset-config-msg-l3": "be ye sure ye want t' proceed?",
"data-copied-msg": "Config has been copied t' clipboardd",
"css-note-l1": "ye will need t' refresh th' page fer yer changes t' take effect.",
"css-note-l2": "Styles overrides be only stored locally, so it be recommended t' make a copy o' yer CSS.",
"css-note-l3": "To remove all custom styles, delete th' contents and hit Save Changes"
},
"settings": {
"sign-in-welcome": "Ahoy {username}!"
},
"updates": {
"app-version-note": "Dashy version",
"up-to-date": "Up-to-Date",
"out-of-date": "Update Available",
"unsupported-version-l1": "You are using a ye' old version of Dashy",
"unsupported-version-l2": "For th' best experience, and recent security patches, please update to"
},
"language-switcher": {
"success-msg": "Language Updated t'"
},
"theme-maker": {
"copied-toast": "Theme data for {theme} copied t' ye clipboard"
},
"config-editor": {
"save-location-label": "Save Location",
"location-local-label": "Apply Locally",
"location-disk-label": "Write Changes to Config File",
"save-button": "Save Changes",
"valid-label": "Config is Valid",
"status-success-msg": "Task Complete",
"status-fail-msg": "Task Failed",
"success-msg-disk": "Th' config file written to disk successfully",
"success-msg-local": "Ye local changes were successfully saved",
"success-note-l1": "th' app should rebuild automatically.",
"success-note-l2": "This may take up t' a minute.",
"success-note-l3": "ye will need t' refresh th' page fer changes t' take effect.",
"error-msg-cannot-save": "An error occurred savin' config",
"error-msg-bad-json": "Error in ye JSON, possibly malformed",
"warning-msg-validation": "Validation Warnin' Ahead",
"not-admin-note": "ye cannot write changed t' disk, because ye be not logged in as an admin"
},
"app-rebuild": {
"title": "Rebuild Application",
"rebuild-note-l1": "A rebuild be required fer changes written t' th' conf.yml file t' take effect.",
"rebuild-note-l2": "This should happen automatically, but if it hasn't, ye can manually trigger it here.",
"rebuild-note-l3": "This be not required fer modifications stored locally.",
"rebuild-button": "Start Build",
"rebuilding-status-1": "Buildin...",
"error-permission": "ye dern't have permission t' trigger this action",
"success-msg": "Ayhyo, build did complete successfully!",
"fail-msg": "Build operation did fail",
"reload-note": "A page reload be now required fer changes t' take effect",
"reload-button": "Reload Ye Page"
},
"cloud-sync": {
"intro-l1": "Cloud backup and restore be an optional feature, that enables ye t' upload yer config t' th' internet, and then restore it on any other device or instance o' Dashy.",
"intro-l2": "All data be fully end-t'-end encrypted with AES, usin' yer password as th' key.",
"intro-l3": "For more info, please see th'",
"backup-title-setup": "Make ye Backup",
"backup-title-update": "Update ye Backup",
"password-label-setup": "Choose ye Password",
"password-label-update": "Enter yer Password",
"backup-id-label": "Yer Backup ID",
"backup-id-note": "This be used t' restore from backups later. So keep it, along with yer password somewhere safe.",
"backup-missing-password": "Missin'g' Password",
"backup-error-unknown": "Unable t' process request",
"backup-error-password": "Incorrect password. Walk the plank! Please enter yer current password."
},
"menu": {
"sametab": "Stay Aboard",
"newtab": "Walk the Plank",
"modal": "Open in ye Pop-Up Ship",
"workspace": "Open on Workspace Deck"
}
}

View File

@ -22,7 +22,7 @@
{{ $t('updates.out-of-date') }}: <b>{{ latestVersion }}</b>
<span class="please-update">
{{ $t('updates.unsupported-version-l1') }}.<br>
{{ $t('updates.unsupported-version-2') }} {{ latestVersion }}
{{ $t('updates.unsupported-version-l2') }} {{ latestVersion }}
</span>
</p>
</div>

View File

@ -279,7 +279,6 @@ export default {
}
&.short:not(.size-large) {
height: 2rem;
.tile-title { overflow: visible; }
}
}
@ -346,6 +345,7 @@ export default {
align-items: center;
height: 2rem;
padding-top: 4px;
max-width: 14rem;
div img, div svg.missing-image {
width: 2rem;
}
@ -353,7 +353,8 @@ export default {
height: fit-content;
min-height: 1.2rem;
text-align: left;
max-width:140px;
max-width: 12rem;
overflow: hidden;
span.text {
text-align: left;
padding-left: 10%;

View File

@ -13,13 +13,13 @@
No Items to Show Yet
</div>
<div v-else
:class="`there-are-items ${isGridLayout? 'item-group-grid': ''}`"
:class="`there-are-items ${isGridLayout? 'item-group-grid': ''} inner-size-${itemSize}`"
:style="gridStyle"
>
<Item
v-for="(item) in sortedItems"
:id="makeId(title, item.title)"
:key="makeId(title, item.title)"
v-for="(item, index) in sortedItems"
:id="makeId(title, item.title, index)"
:key="makeId(title, item.title, index)"
:url="item.url"
:title="item.title"
:description="item.description"
@ -105,18 +105,21 @@ export default {
},
gridStyle() {
let styles = '';
styles += this.displayData.itemCountX
? `grid-template-columns: repeat(${this.displayData.itemCountX}, minmax(0, 1fr));` : '';
styles += this.displayData.itemCountY
? `grid-template-rows: repeat(${this.displayData.itemCountY}, minmax(0, 1fr));` : '';
if (document.body.clientWidth > 600) { // Only proceed if not on tiny screen
styles += this.displayData.itemCountX
? `grid-template-columns: repeat(${this.displayData.itemCountX}, minmax(0, 1fr));` : '';
styles += this.displayData.itemCountY
? `grid-template-rows: repeat(${this.displayData.itemCountY}, minmax(0, 1fr));` : '';
}
return styles;
},
},
methods: {
/* Returns a unique lowercase string, based on name, for section ID */
makeId(sectionStr, itemStr) {
makeId(sectionStr, itemStr, index) {
const charSum = sectionStr.split('').map((a) => a.charCodeAt(0)).reduce((x, y) => x + y);
return `${charSum}_${itemStr.replace(/\s+/g, '-').replace(/[^a-zA-Z ]/g, '').toLowerCase()}`;
const itemTitleStr = itemStr.replace(/\s+/g, '-').replace(/[^a-zA-Z ]/g, '').toLowerCase();
return `${index}_${charSum}_${itemTitleStr}`;
},
/* Opens the iframe modal */
triggerModal(url) {
@ -197,7 +200,7 @@ export default {
grid-template-columns: repeat(var(--item-col-count, 2), minmax(0, 1fr));
}
}
.orientation-horizontal {
.orientation-horizontal:not(.single-section-view) {
display: flex;
flex-direction: column;
.there-are-items {
@ -210,6 +213,16 @@ export default {
@include big-screen-up { --item-col-count: 12; }
grid-template-columns: repeat(var(--item-col-count, 2), minmax(0, 1fr));
}
.there-are-items.inner-size-large {
display: grid;
@include phone { --item-col-count: 1; }
@include tablet { --item-col-count: 2; }
@include laptop { --item-col-count: 3; }
@include monitor { --item-col-count: 5; }
@include big-screen { --item-col-count: 6; }
@include big-screen-up { --item-col-count: 8; }
grid-template-columns: repeat(var(--item-col-count, 2), minmax(0, 1fr));
}
}
</style>

View File

@ -1,52 +1,93 @@
<template>
<nav id="nav">
<div class="nav-outer">
<IconBurger
:class="`burger ${!navVisible ? 'visible' : ''}`"
@click="navVisible = !navVisible"
/>
<nav id="nav" v-if="navVisible">
<router-link
v-for="(link, index) in links"
:key="index"
:to="link.path"
:href="link.path"
:target="isUrl(link.path) ? '_blank' : ''"
rel="noopener noreferrer"
class="nav-item"
v-for="(link, index) in links"
:key="index"
:to="link.path"
:href="link.path"
:target="isUrl(link.path) ? '_blank' : ''"
rel="noopener noreferrer"
class="nav-item"
>{{link.title}}</router-link>
</nav>
</nav>
</div>
</template>
<script>
import IconBurger from '@/assets/interface-icons/burger-menu.svg';
export default {
name: 'Nav',
components: {
IconBurger,
},
props: {
links: Array,
},
data: () => ({
navVisible: true,
isMobile: false,
}),
created() {
this.navVisible = !this.detectMobile();
this.isMobile = this.detectMobile();
},
methods: {
detectMobile() {
const screenWidth = document.body.clientWidth;
return screenWidth && screenWidth < 600;
},
isUrl: (str) => new RegExp(/(http|https):\/\/(\S+)(:[0-9]+)?/).test(str),
},
};
</script>
<style scoped lang="scss">
@import '@/styles/style-helpers.scss';
@import '@/styles/media-queries.scss';
nav {
.nav-outer {
nav {
display: flex;
align-items: center;
.nav-item {
display: inline-block;
padding: 0.75rem 0.5rem;
margin: 0.5rem;
outline: none;
border: none;
border-radius: var(--curve-factor);
-webkit-box-shadow: 1px 1px 2px #232323;
box-shadow: 1px 1px 2px #232323;
color: var(--nav-link-text-color);
background: var(--nav-link-background-color);
border: 1px solid var(--nav-link-border-color);
text-decoration: none;
&.router-link-active, &:hover {
color: var(--nav-link-text-color-hover);
background: var(--nav-link-background-color-hover);
border: 1px solid var(--nav-link-border-color-hover);
}
display: inline-block;
padding: 0.75rem 0.5rem;
margin: 0.5rem;
min-width: 5rem;
text-align: center;
outline: none;
border: none;
border-radius: var(--curve-factor);
-webkit-box-shadow: 1px 1px 2px #232323;
box-shadow: 1px 1px 2px #232323;
color: var(--nav-link-text-color);
background: var(--nav-link-background-color);
border: 1px solid var(--nav-link-border-color);
text-decoration: none;
&.router-link-active, &:hover {
color: var(--nav-link-text-color-hover);
background: var(--nav-link-background-color-hover);
border: 1px solid var(--nav-link-border-color-hover);
}
}
}
/* Mobile and Burger-Menu Styles */
@extend .svg-button;
@include phone {
width: 100%;
nav { flex-wrap: wrap; }
}
.burger {
display: none;
&.visible { display: block; }
@include phone { display: block; }
}
}
</style>

View File

@ -127,6 +127,8 @@ export default {
localStorage.setItem(localStorageKeys.HIDE_SETTINGS, this.settingsVisible);
},
getSettingsVisibility() {
const screenWidth = document.body.clientWidth;
if (screenWidth && screenWidth < 600) return false;
return JSON.parse(localStorage[localStorageKeys.HIDE_SETTINGS]
|| (this.visibleComponents || defaultVisibleComponents).settings);
},
@ -173,6 +175,11 @@ export default {
@include very-tiny-phone {
flex-direction: column;
align-items: baseline;
div {
width: 100%;
text-align: center;
.theme-selector-section { justify-content: center; }
}
}
}

View File

@ -172,6 +172,7 @@ export default {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
height: 100%;
span.theme-label {
font-size: 1rem;

View File

@ -71,7 +71,11 @@ export default {
},
},
mounted() {
this.openDefaultSection();
if (this.sections.length === 1) { // If only 1 section, go ahead and open it
this.openSection(0);
} else { // Otherwise, see if user set a default section, and open that
this.openDefaultSection();
}
},
};
</script>

View File

@ -65,8 +65,12 @@ const makeMetaTags = (defaultTitle) => ({
metaTags: metaTagData,
});
/* Routing mode, can be either 'hash', 'history' or 'abstract' */
const mode = 'history';
/* List of all routes, props, components and metadata */
const router = new Router({
mode,
routes: [
{ // The default view can be customized by the user
path: '/',
@ -80,6 +84,12 @@ const router = new Router({
component: Home,
meta: makeMetaTags('Home Page'),
},
{ // View only single section
path: `${routePaths.home}/:section`,
name: 'home-section',
component: Home,
meta: makeMetaTags('Home Page'),
},
{ // Workspace view page
path: routePaths.workspace,
name: 'workspace',

View File

@ -18,7 +18,7 @@ html[data-theme='thebe'] {
--item-background: #141b33;
--item-background-hover: #060913;
--item-hover-shadow: 0 1px 3px #9660ecb3, 0 1px 2px #9660ecbf;
--primary: #9660ec;
--primary: #b187f5;
--item-group-outer-background: #9660EC
linear-gradient(45deg, #9660ec 2%,#5f60ea 51%,#9660ec 100%);
--font-headings: 'PTMono', 'Courier New', monospace;
@ -26,7 +26,7 @@ html[data-theme='thebe'] {
html[data-theme='dracula'] {
--font-headings: 'Allerta Stencil', sans-serif;
--primary: #6272a4;
--primary: #7a8cc5;
--background: #44475a;
--background-darker: #282a36;
--item-group-background: #282a36;
@ -36,11 +36,13 @@ html[data-theme='dracula'] {
--item-hover-shadow: none;
--settings-text-color: #98ace9;
--config-settings-color: #98ace9;
.collapsable:nth-child(1n) { background: #8be9fd; .item { border: 1px solid #8be9fd; color: #8be9fd; }}
.collapsable:nth-child(2n) { background: #50fa7b; .item { border: 1px solid #50fa7b; color: #50fa7b; }}
.collapsable:nth-child(3n) { background: #ffb86c; .item { border: 1px solid #ffb86c; color: #ffb86c; }}
.collapsable:nth-child(4n) { background: #ff79c6; .item { border: 1px solid #ff79c6; color: #ff79c6; }}
.collapsable:nth-child(4n) { background: #bd93f9; .item { border: 1px solid #bd93f9; color: #bd93f9; }}
--item-group-outer-background: #282a36;
.item { border: 1px solid var(--primary); }
.collapsable:nth-child(1n) label { color: #8be9fd; }
.collapsable:nth-child(2n) label { color: #50fa7b; }
.collapsable:nth-child(3n) label { color: #ffb86c; }
.collapsable:nth-child(4n) label { color: #ff79c6; }
.collapsable:nth-child(4n) label { color: #bd93f9; }
}
html[data-theme='bee'] {
@ -190,9 +192,9 @@ html[data-theme='material-original'] {
--font-body: 'Roboto', serif;
--primary: #29B6F6;
--settings-text-color: #01579b;
--background: #e2e1e0;
--background: #f1f1f1;
--background-darker: #01579B;
--settings-background: #01579B;
--item-group-heading-text-color: #01579B;
--item-group-shadow: none;
--item-group-outer-background: none;
--item-group-background: none;
@ -203,6 +205,7 @@ html[data-theme='material-original'] {
--curve-factor: 2px;
--curve-factor-navbar: 0;
--item-group-padding: 5px 0 0;
--item-text-color: #01579B;
--item-shadow: 0 1px 3px #0000001f, 0 1px 2px #0000003d;
--item-hover-shadow: 0 1px 4px #00000029, 0 2px 4px #0000002a;
--item-icon-transform: drop-shadow(1px 2px 1px var(--transparent-30)) saturate(0.65);
@ -288,6 +291,8 @@ html[data-theme='colorful'] {
--item-group-outer-background: #05070e;
--item-group-heading-text-color: #e8eae1;
--item-group-heading-text-color-hover: #fff;
--item-hover-shadow: 1px 4px 6px #000000;
--nav-link-background-color: #141826;
.item-wrapper:nth-child(1n) { .item { color: #eb5cad; border: 1px solid #eb5cad; } }
.item-wrapper:nth-child(2n) { .item { color: #985ceb; border: 1px solid #985ceb; } }
.item-wrapper:nth-child(3n) { .item { color: #5c90eb; border: 1px solid #5c90eb; } }
@ -300,9 +305,12 @@ html[data-theme='colorful'] {
opacity: 0.85;
outline: none;
background: currentColor;
span { color: #05070e; }
span.text, p.description { color: #05070e; }
i.fas, i.fab, i.far, i.fal, i.fad {
filter: drop-shadow(1px 3px 2px var(--transparent-50));
color: #05070e;
}
svg path { fill: #05070e; }
i.fas, i.fab, i.far, i.fal, i.fad { color: #05070e; }
}
h1, h2, h3, h4 {
font-weight: normal;
@ -354,6 +362,7 @@ html[data-theme='minimal-light'], html[data-theme='minimal-dark'], html[data-the
html[data-theme='material'], html[data-theme='material-dark'] {
--font-body: 'Raleway', serif;
--font-headings: 'Francois One', serif;
--footer-height: 140px;
--curve-factor: 4px;
--curve-factor-navbar: 8px;
--about-page-background: var(--background);
@ -394,6 +403,7 @@ html[data-theme='material'], html[data-theme='material-dark'] {
white-space: pre-wrap;
font-size: .9em;
text-overflow: ellipsis;
min-height: 2rem;
}
}
&.size-large {
@ -817,7 +827,92 @@ html[data-theme='vaporware'] {
// }
}
html[data-theme='cyberpunk'] {
html[data-theme='glow'], html[data-theme=glow-colorful] {
--primary: #5c6da9;
--background: #f6f6f6;
--background-darker: #fff;
--curve-factor: 12px;
--item-group-background: #fff;
--item-group-outer-background: #fff;
--item-background: #fff;
--font-headings: 'Sniglet', cursive;
--item-group-heading-text-color: #5c6da9;
--item-group-heading-text-color-hover: #5c6da9;
--item-group-shadow: 0 5px 16px 0 #9f72ff33;
--item-background-hover: #fff;
--item-shadow: 0 1px 5px 0 #8656ef80;
--item-hover-shadow: 0 1px 8px 0 #8656efa6;
--item-icon-transform: drop-shadow(1px 2px 3px var(--transparent-50)) saturate(0.95);
--item-icon-transform-hover: drop-shadow(1px 2px 4px var(--transparent-50)) saturate(0.95);
--footer-height: 120px;
--transparent-50: #cfcfcf80;
header {
padding: 0.5rem;
.page-titles{
h1 {
font-size: 1.8rem;
}
span.subtitle {
font-size: 0.8rem;
text-shadow: none;
}
}
.nav .nav-item {
padding: 0.2rem 0.4rem;
box-shadow: none;
}
}
.settings-outer {
box-shadow: 0 4px 5px 0 #8656ef1a;
.options-container {
padding: 0.25rem 1.5rem 0.25rem 1rem;
background: var(--background-darker);
}
}
footer {
box-shadow: 0 -4px 5px 0 #8656ef1a;
}
.search-wrap input {
box-shadow: 0 1px 5px 0 #8656ef80;
}
div.collapsable:nth-child(1n) {
a.item { color: #5213dc; }
--item-group-shadow: 0 5px 16px 0 #9f72ff33;
--item-group-heading-text-color: #8656ef;
--item-group-heading-text-color-hover: #783cfb;
--item-background-hover: #fff;
--item-shadow: 0 1px 5px 0 #8656ef80;
--item-hover-shadow: 0 1px 8px 0 #8656efa6;
--item-icon-transform: drop-shadow(1px 2px 3px #8656ef80) saturate(0.95);
--item-icon-transform-hover: drop-shadow(1px 2px 4px #8656ef80) saturate(0.95);
}
div.collapsable:nth-child(2n) {
a.item { color: #b514d8; }
--item-group-shadow: 0 5px 16px 0 #728cff33;
--item-group-heading-text-color: #d356ef;
--item-group-heading-text-color-hover: #d73bf9;
--item-background-hover: #fff;
--item-shadow: 0 1px 5px 0 #d356ef80;
--item-hover-shadow: 0 1px 8px 0 #d356efa6;
--item-icon-transform: drop-shadow(1px 2px 3px #d356ef80) saturate(0.95);
--item-icon-transform-hover: drop-shadow(1px 2px 4px #d356ef80) saturate(0.95);
}
div.collapsable:nth-child(3n) {
a.item { color: #07b9d0; }
--item-group-shadow: 0 5px 16px 0 #728cff33;
--item-group-heading-text-color: #56ddef;
--item-group-heading-text-color-hover: #3cdefb;
--item-background-hover: #fff;
--item-shadow: 0 1px 5px 0 #56ddef80;
--item-hover-shadow: 0 1px 8px 0 #56ddefa6;
--item-icon-transform: drop-shadow(1px 2px 3px #56ddef80) saturate(0.95);
--item-icon-transform-hover: drop-shadow(1px 2px 4px #56ddef80) saturate(0.95);
}
}
html[data-theme='cyberpunk'] {
--pink: #ff2a6d;
--pale: #d1f7ff;
--aqua: #05d9e8;
@ -900,6 +995,8 @@ html[data-theme="dashy-docs"] {
--item-shadow: 4px 4px 6px #00000080, -2px -2px 4px rgb(0 0 0 / 40%);
--item-group-shadow: 0px 3px 2px #222222, 0px 0px 2px #3e3e3e;
--font-headings: 'PTMono', 'Courier New', monospace;
--nav-link-background-color-hover: none;
--nav-link-border-color-hover: none;
footer {
box-shadow: 0 -3px 4px #010101;
@ -913,27 +1010,34 @@ html[data-theme="dashy-docs"] {
background: $first; box-shadow: 0 4px $second;
&:hover { box-shadow: 0 2px $second; }
}
// Section headings, nav bar items and minimal tabs
div.collapsable:nth-child(1n) label.lbl-toggle,
.minimal-section-heading:nth-child(1n),
a.nav-item:nth-child(1n) {
@include make-colors(#db78fc, #b83ddd);
--nav-link-background-color-hover: #db78fc;
--nav-link-border-color-hover: #db78fc;
}
div.collapsable:nth-child(2n) label.lbl-toggle,
.minimal-section-heading:nth-child(2n),
a.nav-item:nth-child(2n) {
@include make-colors(#5c85f7, #3d48dd);
--nav-link-background-color-hover: #5c85f7;
--nav-link-border-color-hover: #5c85f7;
}
div.collapsable:nth-child(3n) label.lbl-toggle,
.minimal-section-heading:nth-child(3n),
a.nav-item:nth-child(3n) {
@include make-colors(#41ef90, #1e9554);
--nav-link-background-color-hover: #41ef90;
--nav-link-border-color-hover: #41ef90;
}
div.collapsable:nth-child(4n) label.lbl-toggle,
.minimal-section-heading:nth-child(4n),
a.nav-item:nth-child(4n) {
@include make-colors(#dcff5a, #ceb73f);
--nav-link-background-color-hover: #dcff5a;
--nav-link-border-color-hover: #dcff5a;
}
nav.side-bar {

View File

@ -10,7 +10,7 @@
/* Basic Page Components */
--scroll-bar-width: 8px;
--header-height: 6.3rem;
--footer-height: 125px;
--footer-height: 128px;
/* Section & Item dimensions */
--item-group-padding: 5px; // Determines width of item-group outline

View File

@ -46,7 +46,7 @@ const getUsers = () => {
// Check if the user is still using previous schema type
if (Array.isArray(auth)) {
printWarning(); // Print warning message
return auth; // Let the user proceed anyway, will remove in V 1.7.0
return []; // Support for old data structure now removed
}
// Otherwise, return the users array, if available
return auth.users || [];
@ -95,12 +95,7 @@ export const isAuthEnabled = () => {
/* Returns true if guest access is enabled */
export const isGuestAccessEnabled = () => {
const appConfig = getAppConfig();
if (appConfig.enableGuestAccess) {
// User is still using the old auth method
printWarning();
return true;
}
if (appConfig.auth && !Array.isArray(appConfig.auth)) {
if (appConfig.auth && typeof appConfig.auth === 'object') {
return appConfig.auth.enableGuestAccess || false;
}
return false;

View File

@ -61,6 +61,7 @@ module.exports = {
'cyberpunk',
'matrix',
'matrix-red',
'glow',
'raspberry-jam',
'bee',
'tiger',
@ -174,7 +175,7 @@ module.exports = {
mdi: 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css',
si: 'https://unpkg.com/simple-icons@v5/icons',
generative: 'https://avatars.dicebear.com/api/identicon/{icon}.svg',
localPath: '/item-icons',
localPath: './item-icons',
faviconName: 'favicon.ico',
homeLabIcons: 'https://raw.githubusercontent.com/WalkxCode/dashboard-icons/master/png/{icon}.png',
},

View File

@ -12,6 +12,7 @@ import hi from '@/assets/locales/hi.json';
import ja from '@/assets/locales/ja.json';
import pt from '@/assets/locales/pt.json';
import ru from '@/assets/locales/ru.json';
import pirate from '@/assets/locales/zz-pirate.json';
// Language data - Next register your language by adding it to this list
export const languages = [
@ -93,6 +94,12 @@ export const languages = [
locale: ru,
flag: '🇷🇺',
},
{ // Joke Language - Pirate
name: 'Pirate',
code: 'pirate',
locale: pirate,
flag: '🏴‍☠️',
},
];
/**

View File

@ -13,11 +13,19 @@
:modalOpen="modalOpen"
class="settings-outer"
/>
<!-- Show back button, when on single-section view -->
<div v-if="singleSectionView">
<router-link to="/home" class="back-to-all-link">
<BackIcon />
<span>Back to All</span>
</router-link>
</div>
<!-- Main content, section for each group of items -->
<div v-if="checkTheresData(sections)"
:class="`item-group-container `
+ `orientation-${layout} `
+ `item-size-${itemSizeBound} `
+ (singleSectionView ? 'single-section-view ' : '')
+ (this.colCount ? `col-count-${this.colCount} ` : '')"
>
<Section
@ -49,12 +57,15 @@ import SettingsContainer from '@/components/Settings/SettingsContainer.vue';
import Section from '@/components/LinkItems/Section.vue';
import { searchTiles } from '@/utils/Search';
import Defaults, { localStorageKeys, iconCdns } from '@/utils/defaults';
import ErrorHandler from '@/utils/ErrorHandler';
import BackIcon from '@/assets/interface-icons/back-arrow.svg';
export default {
name: 'home',
components: {
SettingsContainer,
Section,
BackIcon,
},
data: () => ({
searchValue: '',
@ -74,6 +85,9 @@ export default {
modalOpen() {
return this.$store.state.modalOpen;
},
singleSectionView() {
return this.findSingleSection(this.$store.getters.sections, this.$route.params.section);
},
/* Get class for num columns, if specified by user */
colCount() {
let { colCount } = this.appConfig;
@ -94,7 +108,7 @@ export default {
return this.sections;
},
filteredTiles() {
const sections = this.allSections;
const sections = this.singleSectionView || this.allSections;
return sections.filter((section) => this.filterTiles(section.items, this.searchValue));
},
/* Updates layout (when button clicked), and saves in local storage */
@ -148,6 +162,19 @@ export default {
updateModalVisibility(modalState) {
this.$store.commit('SET_MODAL_OPEN', modalState);
},
/* If on sub-route, and section exists, then return only that section */
findSingleSection: (allSectios, sectionTitle) => {
if (!sectionTitle) return undefined;
let sectionToReturn;
const parse = (section) => section.replace(' ', '-').toLowerCase().trim();
allSectios.forEach((section) => {
if (parse(sectionTitle) === parse(section.name)) {
sectionToReturn = [section];
}
});
if (!sectionToReturn) ErrorHandler(`No section named '${sectionTitle}' was found`);
return sectionToReturn;
},
/* Returns an array of links to external CSS from the Config */
getExternalCSSLinks() {
const availibleThemes = {};
@ -245,6 +272,16 @@ export default {
min-height: calc(99.9vh - var(--footer-height));
}
.back-to-all-link {
display: flex;
align-items: center;
padding: 0.25rem;
margin: 0.25rem;
@extend .svg-button;
svg { margin-right: 0.5rem; }
text-decoration: none;
}
/* Outside container wrapping the item groups*/
.item-group-container {
display: grid;
@ -269,7 +306,7 @@ export default {
flex-direction: row;
}
}
&.orientation-horizontal, &.orientation-vertical {
&.orientation-horizontal, &.orientation-vertical, &.single-section-view {
@include phone { --content-max-width: 100%; }
@include tablet { --content-max-width: 98%; }
@include laptop { --content-max-width: 90%; }
@ -302,6 +339,11 @@ export default {
/* Hide when search term returns nothing */
.no-results { display: none; }
/* When in single-section view mode */
&.single-section-view {
display: block;
}
}
/* Custom styles only applied when there is no sections in config */

1357
yarn.lock

File diff suppressed because it is too large Load Diff