Deletes everything

This commit is contained in:
Alicia Sykes 2021-08-29 19:38:07 +01:00
parent 363edb3704
commit bd6a0b4859
117 changed files with 0 additions and 13978 deletions

View File

@ -1,20 +0,0 @@
---
name: "Add your Dashboard to the Showcase \U0001F5BC"
about: Share a screenshot of your dashboard to the Readme showcase!
title: "[SHOWCASE_REQUEST]"
labels: ''
assignees: ''
---
Please read the instructions here first:
https://github.com/Lissy93/dashy/blob/master/docs/showcase.md#submitting-your-dashboard
### Complete the Following
- **Title of Dashboard**:
- **Link to Screenshot**:
- **Would you like your name/ username included**: Yes/ No
- **Link to your Website/ Profile/ Twitter** (optional)
- **Description** (optional)
Either attach your screenshot here, or include a link to the CDN / image hosting service.

View File

@ -1,22 +0,0 @@
---
name: "Bug Report \U0001F41B"
about: Submit a bug report for an issue you've come across
title: "[BUG]"
labels: "\U0001F41B Bug"
assignees: Lissy93
---
Thank you for taking the time to raise a bug, and sorry that you've had issues with Dashy 😟
**If applicable to your issue, please include:**
- A description of the bug, including actual behavior and if applicable, expected behavior
- Steps to reproduce
- Info about your system (device, OS, browser and browser version)
- Any console errors? If the issue happens at runtime, open up the dev tools [F12], and go to the Console tab. If the output is very long, please use [0bin](https://0bin.net/)
- Any screenshots, if it is a frontend issue
**Before submitting, please ensure that:**
- [ ] This issue has not already been raised
- [ ] You are using the latest version of Dashy
- [ ] You've included the relevant information above

View File

@ -1,17 +0,0 @@
---
name: "Feature Request \U0001F984"
about: Suggest an idea for future development of Dashy
title: "[FEATURE_REQUEST]"
labels: "\U0001F984 Feature Request"
assignees: Lissy93
---
**Is your feature request related to a problem? If so, please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Priority**:
Low: Nice to have / Medium: Would be useful / High: The app does not function without it

View File

@ -1,11 +0,0 @@
---
name: "Question \U0001F937"
about: Got a question about Dashy, deployment, development or usage?
title: "[QUESTION]"
labels: "\U0001F937 Question"
assignees: Lissy93
---
All questions are welcome :)
In the meantime, you might find the answer to your questions in the (recently written) [docs](https://github.com/Lissy93/dashy/tree/master/docs)

View File

@ -1,10 +0,0 @@
---
name: "Share Feedback \U0001F308"
about: Share what you think about Dashy, and any ideas or suggestions you have
title: "[FEEDBACK]"
labels: "\U0001F308 Feedback"
assignees: ''
---

View File

@ -1,30 +0,0 @@
**Thank you for contributing to Dashy! So that your PR can be handled effectively, please populate the following fields (delete sections that are not applicable)**
### Category
> Please indicate the type of change your PR introduces
Bugfix / Feature / Code style update / Refactoring Only / Build related changes / Documentation / Other (please specify)
### Overview
> Briefly outline your new changes...
### Issue Number _(if applicable)_
#00
### New Vars _(if applicable)_
> If you've added any new build scripts, environmental variables, config file options, dependency or devDependency, please outline here
### Screenshot _(if applicable)_
> If you've introduced any significant UI changes, please include a screenshot
### Code Quality Checklist _(Please complete)_
- [ ] All changes are backwards compatible
- [ ] All lint checks and tests are passing
- [ ] There are no (new) build warnings or errors
- [ ] _(If a new config option is added)_ Attribute is outlined in the schema and documented
- [ ] _(If a new dependency is added)_ Package is essential, and has been checked out for security or performance

View File

@ -1,24 +0,0 @@
# This action builds and deploys the master branch
name: Deploy demo of current version
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2.3.1
- name: Install and Build 🔧
run: |
npm install
npm run build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@4.1.4
with:
branch: dev-demo
folder: dist

View File

@ -1,15 +0,0 @@
name: Contributors
on:
schedule:
- cron: '0 1 * * 0' # At 01:00 on Sunday.
push:
branches:
- master
jobs:
contributors:
runs-on: ubuntu-latest
steps:
- uses: bubkoo/contributors-list@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
svgPath: docs/assets/CONTRIBUTORS.svg

20
.gitignore vendored
View File

@ -1,20 +0,0 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@ -1,3 +0,0 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View File

@ -1,47 +0,0 @@
# Alternate Views & Opening Methods
## Views
As well as the default start view, Dashy has several other start pages, for different tasks. You can switch views with the view-switcher button in the top-right, or set a default starting view using the `appConfig.startingView` attribute (can be `default`, `minimal` or `workspace`).
### Default
This is the main page that you will land on when you first launch the application. Here all of your sections and items will be visible, you can modify settings and search + launch your applications.
<p align="center">
<b>Example of Default View</b><br />
<img width="800" src="https://i.ibb.co/L8YbNNc/dashy-demo2.gif" alt="Demo" />
</p>
### Workspace
The workspace view displays your links in a sidebar on the left-hand side, and apps are launched within Dashy. This enables you to use all of your self-hosted apps from one place, and makes multi-tasking easy.
In the workspace view, you can keep previously opened websites/ apps open in the background, by setting `appConfig.enableMultiTasking: true`. This comes at the cost of performance, but does mean that your session with each app is preserved, enabling you to quickly switch between your apps.
<p align="center">
<b>Example of Workspace View</b><br />
<img alt="Workspace view demo" src="https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/workspace-demo.gif" width="800" />
</p>
### Minimal View
The minimal view aims to be super fast and simple, and can be used as a browser startpage. Items are grouped into a tab view, and the last opened tab will be remembered. Similar to the main view, you can search and launch items just by typing, and right-clicking will show more options.
<p align="center">
<b>Example of Minimal View</b><br />
<img alt="Workspace view demo" src="https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/minimal-view-demo.gif" width="800" />
</p>
## Opening Methods
Dashy supports several different ways to launch your apps. The default opening method for each app can be specified using the `target` attribute, with a value of one of the following:
- `sametab` - The app will be launched in the current tab
- `newtab` - The app will be launched in a new tab
- `modal` - Launch app in a resizable/ movable popup modal on the current page
- `workspace` - Changes to Workspace view, and launches app
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`.
<p align="center">
<img width="500" src="https://i.ibb.co/vmZdSRt/dashy-context-menu-2.png" />
</p>
If you get a 'Refused to Connect' error in the modal or workspace views, then the target app has it's X-Frame-Options HTTP set to block requests from embedded content. You can easily fix this by setting this header to ALLOW, for instructions on how to do so, see the [Troubleshooting Docs](/docs/troubleshooting#refused-to-connect-in-modal-or-workspace-view).

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -1,7 +0,0 @@
<svg width="223px" height="30px" version="1.1" viewBox="0 0 223 30" xmlns="http://www.w3.org/2000/svg">
<title>Artboard</title>
<desc>Created with Sketch.</desc>
<rect id="Rectangle" width="223" height="30" rx="8" fill="#ff5e5b" style="fill-rule:evenodd;fill:#ff8eff"/>
<path d="m19.011 10.912c0.57462-1.6874 1.9364-2.531 4.0853-2.531 3.2234 0 4.4184 4.0247 2.7288 6.6559-1.1264 1.7541-3.3978 3.9728-6.8141 6.6559-3.4163-2.6832-5.6877-4.9018-6.8141-6.6559-1.6896-2.6312-0.49462-6.6559 2.7288-6.6559 2.1489 0 3.5107 0.84368 4.0853 2.531z" fill="#ff5e5b" style="fill:none;stroke-width:1.5;stroke:#fff"/>
<text x="55" y="20" style="fill:#ffffff;font-family:sans-serif;font-size:16px;letter-spacing:0px;line-height:1.25;word-spacing:0px" xml:space="preserve"><tspan x="31.423412" y="20.493532" style="fill:#ffffff;font-size:16px">Sponsor me on Github</tspan></text>
</svg>

Before

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

View File

@ -1,276 +0,0 @@
# Authentication
- [Basic Auth](#built-in-auth)
- [Setting Up Authentication](#setting-up-authentication)
- [Hash Password](#hash-password)
- [Logging In and Out](#logging-in-and-out)
- [Security](#security)
- [Keycloak Auth](#keycloak)
- [Deploying Keycloak](#1-deploy-keycloak)
- [Setting up Keycloak](#2-setup-keycloak-users)
- [Configuring Dashy for Keycloak](#3-enable-keycloak-in-dashy-config-file)
- [Alternative Authentication Methods](#alternative-authentication-methods)
- [VPN](#vpn)
- [IP-Based Access](#ip-based-access)
- [Web Server Authentication](#web-server-authentication)
- [OAuth Services](#oauth-services)
- [Auth on Cloud Hosting Services](#static-site-hosting-providers)
## Built-In Auth
Dashy has a basic login page included, and frontend authentication. You can enable this by adding users to the `auth` section under `appConfig` in your `conf.yml`. If this section is not specified, then no authentication will be required to access the app, and it the homepage will resolve to your dashboard.
### Setting Up Authentication
The `auth` property takes an array of users. Each user needs to include a username, hash and optional user type (`admin` or `normal`). The hash property is a [SHA-256 Hash](https://en.wikipedia.org/wiki/SHA-2) of your desired password.
For example:
```yaml
appConfig:
auth:
users:
- user: alicia
hash: 4D1E58C90B3B94BCAD9848ECCACD6D2A8C9FBC5CA913304BBA5CDEAB36FEEFA3
type: admin
- user: bob
hash: 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
```
### Hash Password
Dashy uses [SHA-256 Hash](https://en.wikipedia.org/wiki/Sha-256), a 64-character string, which you can generate using an online tool, such as [this one](https://passwordsgenerator.net/sha256-hash-generator/) or [CyberChef](https://gchq.github.io/CyberChef/) (which can be self-hosted/ ran locally).
A hash is a one-way cryptographic function, meaning that it is easy to generate a hash for a given password, but very hard to determine the original password for a given hash. This means, that so long as your password is long, strong and unique, it is safe to store it's hash in the clear. Having said that, you should never reuse passwords, hashes can be cracked by iterating over known password lists, generating a hash of each.
### Logging In and Out
Once authentication is enabled, so long as there is no valid token in cookie storage, the application will redirect the user to the login page. When the user enters credentials in the login page, they will be checked, and if valid, then a token will be generated, and they can be redirected to the home page. If credentials are invalid, then an error message will be shown, and they will remain on the login page. Once in the application, to log out the user can click the logout button (in the top-right), which will clear cookie storage, causing them to be redirected back to the login page.
### Enabling Guest Access
With authentication setup, by default no access is allowed to your dashboard without first logging in with valid credentials. Guest mode can be enabled to allow for read-only access to a secured dashboard by any user, without the need to log in. A guest user cannot write any changes to the config file, but can apply modifications locally (stored in their browser). You can enable guest access, by setting `appConfig.enableGuestAccess: true`.
### Granular Access
You can use the following properties to make certain sections only visible to some users, or hide sections from guests.
- `hideForUsers` - Section will be visible to all users, except for those specified in this list
- `showForUsers` - Section will be hidden from all users, except for those specified in this list
- `hideForGuests` - Section will be visible for logged in users, but not for guests
For Example:
```yaml
- name: Code Analysis & Monitoring
icon: fas fa-code
displayData:
cols: 2
hideForUsers: [alicia, bob]
items:
...
```
```yaml
- name: Deployment Pipelines
icon: fas fa-rocket
displayData:
hideForGuests: true
items:
...
```
### Security
Since all authentication is happening entirely on the client-side, it is vulnerable to manipulation by an adversary. An attacker could look at the source code, find the function used generate the auth token, then decode the minified JavaScript to find the hash, and manually generate a token using it, then just insert that value as a cookie using the console, and become a logged in user. Therefore, if you need secure authentication for your app, it is strongly recommended to implement this using your web server, or use a VPN to control access to Dashy. The purpose of the login page is merely to prevent immediate unauthorized access to your homepage.
Addressing this is on the todo list, and there are several potential solutions:
1. Encrypt all site data against the users password, so that an attacker can not physically access any data without the correct decryption key
2. Use a backend service to handle authentication and configuration, with no user data returned from the server until the correct credentials are provided. However, this would require either Dashy to be run using it's Node.js server, or the use of an external service
3. ~~Implement authentication using a self-hosted identity management solution, such as [Keycloak for Vue](https://www.keycloak.org/securing-apps/vue)~~ **This is now implemented, and released in PR #174 of V 1.6.5!**
**[⬆️ Back to Top](#)**
---
## Keycloak
Dashy also supports using a [Keycloack](https://www.keycloak.org/) authentication server. The setup for this is a bit more involved, but it gives you greater security overall, useful for if your instance is exposed to the internet.
[Keycloak](https://www.keycloak.org/about.html) is a Java-based [open source](https://github.com/keycloak/keycloak), high-performance, secure authentication system, supported by [RedHad](https://www.redhat.com/en). It is easy to setup ([with Docker](https://quay.io/repository/keycloak/keycloak)), and enables you to secure multiple self-hosted applications with single-sign on using standard protocols (OpenID Connect, OAuth 2.0, SAML 2.0 and social login). It's also very customizable, you can write or use custom [themes](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_development/topics/themes.html), [plugins](https://www.keycloak.org/extensions.html), [password policies](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/authentication/password-policies.html) and more.
The following guide will walk you through setting up Keycloak with Dashy. If you already have a Keycloak instance configured, then skip to Step 3.
### 1. Deploy Keycloak
First thing to do is to spin up a new instance of Keycloak. You will need [Docker installed](https://docs.docker.com/engine/install/), and can then choose a tag, and pull the container from [quay.io/keycloak/keycloak](https://quay.io/repository/keycloak/keycloak)
Use the following run command, replacing the attributes (default credentials, port and name), or incorporate this into your docker-compose file.
```bash
docker run -d \
-p 8081:8080 \
--name auth-server \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin \
quay.io/keycloak/keycloak:15.0.2
```
If you need to pull from DockerHub, a non-official image is available [here](https://registry.hub.docker.com/r/jboss/keycloak). Or if you would prefer not to use Docker, you can also directly install Keycloak from source, following [this guide](https://www.keycloak.org/docs/latest/getting_started/index.html).
You should now be able to access the Keycloak web interface, using the port specified above (e.g. `http://127.0.0.1:8081`), login with the default credentials, and when prompted create a new password.
### 2. Setup Keycloak Users
Before we can use Keycloak, we must first set it up with some users. Keycloak uses Realms (similar to tenants) to create isolated groups of users. You must create a Realm before you will be able to add your first user.
1. Head over to the admin console
2. In the top-left corner there is a dropdown called 'Master', hover over it and then click 'Add Realm'
3. Give your realm a name, and hit 'Create'
You can now create your first user.
1. In the left-hand menu, click 'Users', then 'Add User'
2. Fill in the form, including username and hit 'Save'
3. Under the 'Credentials' tab, give the new user an initial password. They will be prompted to change this after first login
The last thing we need to do in the Keycloak admin console is to create a new client
1. Within your new realm, navigate to 'Clients' on the left-hand side, then click 'Create' in the top-right
2. Choose a 'Client ID', set 'Client Protocol' to 'openid-connect', and for 'Valid Redirect URIs' put a URL pattern to where you're hosting Dashy (if you're just testing locally, then * is fine), and do the same for the 'Web Origins' field
3. Make note of your client-id, and click 'Save'
### 3. Enable Keycloak in Dashy Config File
Now that your Keycloak instance is up and running, all that's left to do is to configure Dashy to use it. Under `appConfig`, set `auth.enableKeycloak: true`, then fill in the details in `auth.keycloak`, including: `serverUrl` - the URL where your Keycloak instance is hosted, `realm` - the name you gave your Realm, and `clientId` - the Client ID you chose.
For example:
```yaml
appConfig:
...
auth:
enableKeycloak: true
keycloak:
serverUrl: 'http://localhost:8081'
realm: 'alicia-homelab'
clientId: 'dashy'
```
Your app is now secured :) When you load Dashy, it will redirect to your Keycloak login page, and any user without valid credentials will be prevented from accessing your dashboard.
From within the Keycloak console, you can then configure things like user permissions, time outs, password policies, access, etc. You can also backup your full Keycloak config, and it is recommended to do this, along with your Dashy config. You can spin up both Dashy and Keycloak simultaneously and restore both applications configs using a `docker-compose.yml` file, and this is recommended.
---
## Alternative Authentication Methods
If you are self-hosting Dashy, and require secure authentication to prevent unauthorized access, then you can either use Keycloak, or one of the following options:
- [Authentication Server](#authentication-server) - Put Dashy behind a self-hosted auth server
- [VPN](#vpn) - Use a VPN to tunnel into the network where Dashy is running
- [IP-Based Access](#ip-based-access) - Disallow access from all IP addresses, except your own
- [Web Server Authentication](#web-server-authentication) - Enable user control within your web server or proxy
- [OAuth Services](#oauth-services) - Implement a user management system using a cloud provider
- [Password Protection (for cloud providers)](#static-site-hosting-providers) - Enable password-protection on your site
### Authentication Server
##### Authelia
[Authelia](https://www.authelia.com/) is an open-source full-featured authentication server, which can be self-hosted and either on bare metal, in a Docker container or in a Kubernetes cluster. It allows for fine-grained access control rules based on IP, path, users etc, and supports 2FA, simple password access or bypass policies for your domains.
- `git clone https://github.com/authelia/authelia.git`
- `cd authelia/examples/compose/lite`
- Modify the `users_database.yml` the default username and password is authelia
- Modify the `configuration.yml` and `docker-compose.yml` with your respective domains and secrets
- `docker-compose up -d`
For more information, see the [Authelia docs](https://www.authelia.com/docs/)
### VPN
A catch-all solution to accessing services running from your home network remotely is to use a VPN. It means you do not need to worry about implementing complex authentication rules, or trusting the login implementation of individual applications. However it can be inconvenient to use on a day-to-day basis, and some public and corporate WiFi block VPN connections. Two popular VPN protocols are [OpenVPN](https://openvpn.net/) and [WireGuard](https://www.wireguard.com/)
### IP-Based Access
If you have a static IP or use a VPN to access your running services, then you can use conditional access to block access to Dashy from everyone except users of your pre-defined IP address. This feature is offered by most cloud providers, and supported by most web servers.
##### Apache
In Apache, this is configured in your `.htaccess` file in Dashy's root folder, and should look something like:
```
Order Deny,Allow
Deny from all
Allow from [your-ip]
```
##### NGINX
In NGINX you can specify [control access](https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/) rules for a given site in your `nginx.conf` or hosts file. For example:
```
server {
listen 80;
server_name www.dashy.example.com;
location / {
root /path/to/dashy/;
passenger_enabled on;
allow [your-ip];
deny all;
}
}
```
##### Caddy
In Caddy, [Request Matchers](https://caddyserver.com/docs/caddyfile/matchers) can be used to filter requests
```
dashy.site {
@public_networks not remote_ip [your-ip]
respond @public_networks "Access denied" 403
}
```
### Web Server Authentication
Most web servers make password protecting certain apps very easy. Note that you should also set up HTTPS and have a valid certificate in order for this to be secure.
##### Apache
First crate a `.htaccess` file in Dashy's route directory. Specify the auth type and path to where you want to store the password file (usually the same folder). For example:
```
AuthType Basic
AuthName "Please Sign into Dashy"
AuthUserFile /path/dashy/.htpasswd
require valid-user
```
Then create a `.htpasswd` file in the same directory. List users and their hashed passwords here, with one user on each line, and a colon between username and password (e.g. `[username]:[hashed-password]`). You will need to generate an MD5 hash of your desired password, this can be done with an [online tool](https://www.web2generators.com/apache-tools/htpasswd-generator). Your file will look something like:
```
alicia:$apr1$jv0spemw$RzOX5/GgY69JMkgV6u16l0
```
##### NGINX
NGINX has an [authentication module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html) which can be used to add passwords to given sites, and is fairly simple to set up. Similar to above, you will need to create a `.htpasswd` file. Then just enable auth and specify the path to that file, for example:
```
location / {
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}
```
##### Caddy
Caddy has a [basic-auth](https://caddyserver.com/docs/caddyfile/directives/basicauth) directive, where you specify a username and hash. The password hash needs to be base-64 encoded, the [`caddy hash-password`](https://caddyserver.com/docs/command-line#caddy-hash-password) command can help with this. For example:
```
basicauth /secret/* {
alicia JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX
}
```
For more info about implementing a single sign on for all your apps with Caddy, see [this tutorial](https://joshstrange.com/securing-your-self-hosted-apps-with-single-signon/)
##### Lighttpd
You can use the [mod_auth](https://doc.lighttpd.net/lighttpd2/mod_auth.html) module to secure your site with Lighttpd. Like with Apache, you need to first create a password file listing your usersnames and hashed passwords, but in Lighttpd, it's usually called `.lighttpdpassword`.
Then in your `lighttpd.conf` file (usually in the `/etc/lighttpd/` directory), load in the mod_auth module, and configure it's directives. For example:
```
server.modules += ( "mod_auth" )
auth.debug = 2
auth.backend = "plain"
auth.backend.plain.userfile = "/home/lighttpd/.lighttpdpassword"
$HTTP["host"] == "dashy.my-domain.net" {
server.document-root = "/home/lighttpd/dashy.my-domain.net/http"
server.errorlog = "/var/log/lighttpd/dashy.my-domain.net/error.log"
accesslog.filename = "/var/log/lighttpd/dashy.my-domain.net/access.log"
auth.require = (
"/docs/" => (
"method" => "basic",
"realm" => "Password protected area",
"require" => "user=alicia"
)
)
}
```
Restart your web server for changes to take effect.
### OAuth Services
There are also authentication services, such as [Ory.sh](https://www.ory.sh/), [Okta](https://developer.okta.com/), [Auth0](https://auth0.com/), [Firebase](https://firebase.google.com/docs/auth/). Implementing one of these solutions would involve some changes to the [`Auth.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/Auth.js) file, but should be fairly straight forward.
### Static Site Hosting Providers
If you are hosting Dashy on a cloud platform, you will probably find that it has built-in support for password protected access to web apps. For more info, see the relevant docs for your provider, for example: [Netlify Password Protection](https://docs.netlify.com/visitor-access/password-protection/), [Cloudflare Access](https://www.cloudflare.com/teams/access/), [AWS Cognito](https://aws.amazon.com/cognito/), [Azure Authentication](https://docs.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service) and [Vercel Password Protection](https://vercel.com/docs/platform/projects#password-protection).
**[⬆️ Back to Top](#)**

View File

@ -1,110 +0,0 @@
# Cloud Backup and Restore
Dashy has a built-in feature for securely backing up your config to a hosted cloud service, and then restoring it on another instance. This feature is totally optional, and if you do not enable it, then Dashy will not make any external network requests.
This is useful not only for backing up your configuration off-site, but it also enables Dashy to be used without having write a YAML config file, and makes it possible to use a public hosted instance, without the need to self-host.
<p align="center">
<img src="https://i.ibb.co/p4pxSqX/dashy-backup-restore.png" width="600" />
</p>
### How it Works
All data is encrypted before being sent to the backend. In Dashy, this is done in [`CloudBackup.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/CloudBackup.js), using [crypto.js](https://github.com/brix/crypto-js)'s AES method, using the users chosen password as the key. The data is then sent to a [Cloudflare worker](https://developers.cloudflare.com/workers/learning/how-workers-works) (a platform for running serverless functions), and stored in a [KV](https://developers.cloudflare.com/workers/learning/how-kv-works) data store.
### Creating a Backup
Once you've got Dashy configured to your preference, open the Backup & Restore menu (click the Cloud icon in the top-right corner). Here you will be prompted to choose a password, which will be used to encrypt your data. If you forget this password, there will be no way to recover your config. After clicking 'Backup' your data will be encrypted, compressed and sent to the hosted cloud service. A backup ID will be returned (in the format of xxxx-xxxx-xxxx-xxxx), this is what you use, along with your password to restore the backup on another system, so take note of it. To update a backup, return to this menu, enter your password, and click 'Update Backup'.
### Restoring a Backup
To restore a backup, navigate to the Backup & Restore menu, and under restore, enter your backup ID, and the password you chose. Your config file will be downloaded, decrypted and applied to local storage.
### Privacy & Security
Data is only ever sent to the cloud when the user actively triggers a backup. All transmitted data is first encrypted using [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard). Your selected password never leaves your device, and is hashed before being compared. It is only possible to restore a configuration if you have both the backup ID and decryption password.
Because the data is encrypted on the client-side (before being sent to the cloud), it is not possible for a man-in-the-middle, government entity, website owner, or even Cloudflare to be able read any of your data. The biggest risk to your data, would be a weak password, or a compromised system.
Having said that, although the code uses robust security libraries and is open source- it was never intended to be a security product, and has not been audited, and therefore cannot be considered totally secure - please keep that in mind.
### Fair Use Policy
Maximum of 24mb of storage per user. Please do not repeatedly hit the endpoint, as if the quota is exceeded the service may become less available to other users. Abuse may result in your IP being temporarily banned by Cloudflare.
---
### Self-Hosting the Backup Server
#### Quick Start
- Install Wrangler CLI Tool: `npm i -g @cloudflare/wrangler`
- Log into Cloudflare account: `wrangler login`
- Create a new project: ` wrangler generate my-project`
- Install dependencies: `cd my-project` && `npm i`
#### Populate `wrangler.toml`
- Add your `account_id` (found on the right sidebar of the Workers or Overview Dashboard)
- Add your `zone_id` (found in the Overview tab of your desired domain on Cloudflare)
- Add your `route`, which should be a domain or host, supporting a wildcard
```toml
name = "dashy-worker"
type = "javascript"
workers_dev = true
route = "example.com/*"
zone_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
account_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
kv_namespaces = [
{ binding = "DASHY_CLOUD_BACKUP", id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }
]
```
#### Complete `index.js`
- Write code to handle your requests, and interact with any other data sources in this file
- Generally, this is done within an event listener for 'fetch', and returns a promise
- For Example:
```javascript
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
return new Response('Hello World!', {
headers: { 'content-type': 'text/plain' },
})
}
```
- For the code used for Dashy's cloud service, see [here](https://gist.github.com/Lissy93/d19b43d50f30e02fa25f349cf5cb5ed8#file-index-js)
#### Commands
- `wrangler dev` - To start the wrangler development server
- `wrangler publish` - To publish to your cloudflare account (first run `wrangler login`)
### API
There are four endpoints, and to keep things simple, they all use the same base URL/ route.
- **`GET`** - Get config for a given user
- `backupId` - The ID of the desired encrypted object
- `subHash` - The latter half of the password hash, to verify ownership
- **`POST`** - Save a new config object, and returns `backupId`
- `userData` - The encrypted, compressed and stringified user config
- `subHash` - The latter half of the password hash, to verify ownership
- **`PUT`** - Update an existing config object
- `backupId` - The ID of the object to update
- `subHash` - Part of the hash, to verify ownership of said object
- `userData` - The new data to store
- **`DELETE`** - Delete a specified config object
- `backupId` - The ID of the object to be deleted
- `subHash` - Part of the password hash, to verify ownership of the object
For more info, see the [API Docs](https://documenter.getpostman.com/view/2142819/TzXumzce).
If you are using Postman, you may find this pre-made [collection](https://www.getpostman.com/collections/58f79ddb150223f67b35) helpful in getting things setup.

View File

@ -1,407 +0,0 @@
# Changelog
## ✨ 1.6.9 - Web Search Feature [PR #185](https://github.com/Lissy93/dashy/pull/185)
- Adds ability to search the web directly from Dashy by pressing enter on the search bar
- Adds configuration options, for setting default search engine, opening method and disabling
- Adds text under search bar, implements into minimal view also
## ⚡️ 1.6.8 - Improved Loading Experience [PR #183](https://github.com/Lissy93/dashy/pull/183)
- During app initialization, show the build progress and status message
- While requests are being made, show loader at top of screen
- Also adds some UI improvements to Workspace view
## ⚡️ 1.6.7 - Option for non-SSL status checks plus minor things [PR #182](https://github.com/Lissy93/dashy/pull/182)
- Adds an option for user to use status checks with non-HTTPS services, Re: #181
- Updates the .env template, plus the variables used in the server
- Uses the v-cloak to hide text before it's finished loading
- Fixed the parsing of the update-checker during build
## ⚡️ 1.6.6 - Improved Search & Shortcuts [PR #175](https://github.com/Lissy93/dashy/pull/175)
- Refactors the search algorithm to improve performance and code reusability
- Updates search to ignore case, special characters and minor-typos
- Adds the option for user to specify tags, which can be used for searching
## ✨ 1.6.5 - Adds support for Secure Authentication using Keycloak [PR #174](https://github.com/Lissy93/dashy/pull/174)
- Major restructure of auth config
- Implements keycloak support, adds docs and updates schema
## ✨ 1.6.4 - Adds functionality for Granular Auth Control [PR #171](https://github.com/Lissy93/dashy/pull/171)
- Enables sections to be visible for all users except for those specified
- Enables sections to be hidden from all users except for those specified
- Enables sections to be hidden from guests, but visible to all authenticated users
## ⚡️ 1.6.3 - Dependency and Build File Updates [PR #168](https://github.com/Lissy93/dashy/pull/168)
- Removes any dependencies which are not 100% essential
- Moves packages that are only used for building into devDependencies
- Updates dependencies to latest version
- Adds a .dockerignore, so that non-essential files are not included in the container
- Updates deployment config files for Netlify, Heroku and GH actions
- Made a brand new bug-report template, with input fields and validation!
## ✨ 1.6.2 - Support for Guest Access [PR #167](https://github.com/Lissy93/dashy/pull/167)
- Adds functionality for optional read-only guest access to dashboards with authentication
- Can be enabled by setting `appConfig.enableGuestAccess: true`
## 💄 1.6.1 - Adds new Theme [PR #166](https://github.com/Lissy93/dashy/issues/166)
- Adds Dashy theme, for use in the dev dashboard
## ✨ 1.5.9 - New Minimal/ Startpage View [PR #155](https://github.com/Lissy93/dashy/issues/155)
- Adds a new view, called minimal view, designed to be like a light-weight startpage
- Implemented all the required features (filtering, opening methods, icons, etc) into minimal view
- Adds `appConfig.startingView` into schema, for specifying the initial default view to be loaded
## ✨ 1.5.8 - Multi-Tasking Support in Workspace View [PR #146](https://github.com/Lissy93/dashy/pull/146)
- Adds option to keep launched apps open in the background, to reduce friction when switching between websites, Re: #144
- This can be enabled by setting `appConfig.enableMultiTasking: true`
- Note that having many apps opened simultaneously, will have an impact on performance
## ✨ 1.5.7 - Adds Support for Material Design Icons [PR #141](https://github.com/Lissy93/dashy/pull/141)
- Enables user to use any icon from [materialdesignicons.com](https://dev.materialdesignicons.com/icons), Re: #139
- Also adds support for [simpleicons.org](https://simpleicons.org/)
- Assets only loaded when needed
- Adds docs for using MDI icons
## ⚡️ 1.5.6 - Refactor + Couple of small things [PR #135](https://github.com/Lissy93/dashy/pull/135)
- The main Dockerfile now uses yarn.lock instead of package-lock.json
- Adds a check to verify password is not empty in cloud backup screen
- Improves responsiveness of config modals for mobile devices
- Enables the user to use their own self-hosted Sentry instance
- Removes the View Config tab of the Config menu, as not needed
- Updates and fixes some typos in the readme
## 🌐 1.5.5 - Adds Missing Translations + Small UI Issues [PR #129](https://github.com/Lissy93/dashy/pull/129)
- Adds missing translations to several UI elements, Re: #126
- Fixes login translations not being picked up on page load, Re: #127
- Fixes small text overflow glitch in config icon, Re: #123
- Several small UI improvements: height of config editor, scrollbar on theme dropdown, page height, white-on-white on material theme, etc
- Adds an action to auto-assign reviewer based on ./.github/CODEOWNERS file
## 🐳 1.5.4 - Docker ARM Support [PR #122](https://github.com/Lissy93/dashy/pull/122)
- Adds a Dockerfile for `arm64v8` and `arm32v7`, to support Raspberry Pi and other modern ARM-based devices
- Sets up automated workflow to publish ARM containers to DockerHub after every new release
- Adds documentation for running Dashy on RPi/ ARM-based devices, Re: #117
## 🩹 1.5.3 - UI Quick Fix [PR #121](https://github.com/Lissy93/dashy/pull/121)
- Downgrades and pins vue-material-tabs to 0.1.5, to prevent breaking changes. Fixes #118 p1
- Sets auto-width for theme selector, so text doesn't wrap for long theme names. Fixes #119
- Uses flex layout for config menu, so note doesn't overlap menu on small screens. Fixes #118 p2
## 🌐 1.5.2 - Adds Dutch Translations [PR #120](https://github.com/Lissy93/dashy/pull/120)
- Dutch language support, contributed by @evroon
## 🩹 1.5.1 - UI Quick Fix [PR #116](https://github.com/Lissy93/dashy/pull/116)
- Uses min-max width parent layout, to prevent longer languages (e.g. French) text overflow. Fixes #115
## 🔒 1.5.0 - Improve Robustness of Auth [PR #113](https://github.com/Lissy93/dashy/pull/113)
- Use both username + password for generating token, so that a change in either will log the user out
- Prevent privilege escalation by disallowing a user from modifying their user type through the UI
- Improve the isAuthenticated check, by taking account of empty users array
## ✨ 1.4.8 - Optional Crash Reports [PR #112](https://github.com/Lissy93/dashy/pull/112)
- Adds an optional, off by default method of getting crash reports
- This can be enabled in `appConfig.enableErrorReporting`, and will not be used at all unless explicitly activated by user
- This is needed for when a user raises a bug which is hard to fix
- Also improves robustness of config accumulator, don't throw error when config is missing
- Adds Privacy & Security docs
## ♻️ 1.4.7 - Refactor [PR #110](https://github.com/Lissy93/dashy/pull/110)
- Moves cloud sync dialog into the config menu, and removes icon on homepage
- Fixes typo in Default theme name, Re #106
- Spell checks readme
- Updates the contributor CI action, that generates list of contributors + sponsors
## 📝 1.4.6 - Documentation Updates [PR #108](https://github.com/Lissy93/dashy/pull/108)
- Breaks many of the longer files into several more digestible articles
- Writes repo pages including, Security, Code of Conduct, Legal, Updates license
- Makes an automatically generated Credits page
- Adds a contributing page, with several ways that users can help out
- Implements this changelog, as requested in #87
## 🌐 1.4.5 - Adds German Translations [PR #107](https://github.com/Lissy93/dashy/pull/107)
- German language support, contributed by @Niklashere
## ✨ 1.4.4 - Adds Support for Logo Image [PR #105](https://github.com/Lissy93/dashy/pull/105)
- Adds option in config file for user to specify path to an image
- If found, will display said image in the header
## ✨ 1.4.3 - Auto-Checks for Updates [PR #101](https://github.com/Lissy93/dashy/pull/101) and [PR #102](https://github.com/Lissy93/dashy/pull/102)
- Write a script to compare current version with git master version
- Periodically checks for updates, and displays message to user
- Enables user to disable update-checks in the config file
- Checks not using vulnerable version on project-build
## ✨ 1.4.2 - Adds Multi-Language Support [PR #99](https://github.com/Lissy93/dashy/pull/99)
- Implements vue-i18n, sets object globally
- Extracts all text to a single JSON file
- Auto-detects users language, and applies, if availible
- Builds a form to let user manually select their language
- Lets users language be saved and read from local storage, or config file
## ✨ 1.4.1 - Adds Support for Custom Key Bindings [PR #94](https://github.com/Lissy93/dashy/pull/94)
- Adds new attribute under item for saving numeric key binding
- Listens for keypress, and launches corresponding item, if found
## ✨ 1.4.0 - Builds a Custom Theme Configurator
- Adds property to save custom theme variables
- Builds UI form, with color pickers, a pallette and popup
- Integrates the saving colors, and applying saved colors functionality
## 🔨 1.3.9 - Enable Custom Styesheet in Docker [PR #92](https://github.com/Lissy93/dashy/pull/92)
- Enables the user to pass a custom stylesheet in with Docker
- Adds support for 1-Click deployment to Render.com
## 🌟 1.3.8 - Showcase [#91](https://github.com/Lissy93/dashy/pull/91)
- Adds @Shadowking001's screenshot to showcase
## 🌟 1.3.7 - Showcase [PR #84](https://github.com/Lissy93/dashy/pull/84)
- Adds @dtctek's screenshot to showcase
## ✨ 1.3.6 - Enables User to Hide Unwanted Components [PR #78](https://github.com/Lissy93/dashy/pull/78)
- Adds several additional options to the config, allowing the user to hide structural components that they don't need
- Including hideHeading, hideNav, hideSearch, hideSettings, hideFooter, hideSplashScreen
## ✨ 1.3.5 - Adds Support for Emoji Icons [PR #76](https://github.com/Lissy93/dashy/pull/76)
- Enables user to use emojis for item and section icons
- Adds a handler to convert Unicode, or Shortcode into an Emoji
## 🌟 1.3.4 - Showcase Addition [PR #75](https://github.com/Lissy93/dashy/pull/75)
- Adds @cerealconyogurt's screenshot to the showcase
## 💄 1.3.3 - UI Improvements [PR #73](https://github.com/Lissy93/dashy/pull/73)
- New style of Large item
- 2 new color themes
- Added CSS variables for search label and footer background
- Improves process for auto-checking if font-awesome is needed
- Silences non-critical warnings in production build
- Adds new optional font-face for cyber punk
- Shortens readme, and adds contribute links to showcase
## ⚡️ 1.3.0 - Custom Headers for Status Check [PR #72](https://github.com/Lissy93/dashy/pull/72)
- Enables user to pass custom headers to the status check endpoint
- Enables user to use a different URL for the status check request
## 🌟 1.2.9 - Creates a Showcase Page [PR #68](https://github.com/Lissy93/dashy/pull/68)
- Adds a page in the docs for users to share their screenshots of their dashboard
## ✨ 1.2.8 - Adds Remember-Me Functionality into the Login Form [PR #66](https://github.com/Lissy93/dashy/pull/66)
- Adds a dropdown menu in the login form with various time intervals available
- Adds appropriate expiry into session storage, in order to keep user logged in for their desired time interval
## ✨ 1.2.7 - Implements a Right-Click Context Menu [#62](https://github.com/Lissy93/dashy/pull/62)
- Built a context menu, showing all item opening methods, on right-click
- Made a clickOutside directive, in order to close menu when user clicks away
- Adds launching functionality, user can click to launch
## ⚡️ 1.2.6 - Make Font Assets Local [PR #60](https://github.com/Lissy93/dashy/pull/60)
- Downloaded font files to assets
- Removed all calls to font CDN, replaced with local calls
## 🐛 1.2.5 - Small Fixes, and Efficiency Improvements [PR #57](https://github.com/Lissy93/dashy/pull/57)
- Adds correct license
- Improves service workers, and adds serviceWorkerStatus local storage item
- Adds missing statusCheck and statusCheckInterval docs into Configuring.md
- Adds an About App page, containing info needed to raise a bug report
- Adds TDLR license into main readme
- Introduces app versioning
- Adds safeguards into ConfigAccumalaror, to prevent error being thrown
- Updates PR template
- Improved Webpack build experience, with progress bar and completion notification
- Adds new and improved icons for layout options
- Make the Page Title into a home page link
- Adds missing favicon, fixes #55
- Adds assets to PWA manifest.json
- Documents app commands in readme
- Enable passing website as URL param to the workspace
- Modified items, so that title text doesn't get shortened,
## ✨ 1.2.4 - Adds Support for Continuous Status Checking [#52](https://github.com/Lissy93/dashy/pull/52)
- Enables user to re-call the status check at a specified interval
- Processes interval in ms, and updates the traffic light when required
## 🐛 1.2.3 - Bug Fix [PR #49](https://github.com/Lissy93/dashy/pull/49)
- Removes duplicate Docker env var, fixes #48
## ✨ 1.2.2 - Better Favicon Support
- Enables user to force direct/ local favicon fetching
- Adds support for additional favicon API, returning high-res app icons
- Adds support for generative icons
## 🐛 1.2.1 - Bugfix [#44](https://github.com/Lissy93/dashy/pull/44)
- Fixes footer positioning on mobile, makes sticky, fixes #42
## ✨ 1.2.0 - Adds Writing Config to Disk from UI Functionality [PR #43](https://github.com/Lissy93/dashy/pull/43)
- Creates a new server endpoint for handling the backing up of a the file
- Adds backup existing file functionality
- Adds writing new file functionality
- Does error checking, testing and adds some security parameters
- Adds a radio button in the UI, so user chan choose save method
- Process config within the UI, convert to YAML, and write changes to disk
## 🐛 1.1.8 - Bugfix [#40](https://github.com/Lissy93/dashy/pull/40)
- Status check tooltip was not visible in Material themes, raised in issue #39
## ✨ 1.1.7 - Adds Workspace View [PR #38](https://github.com/Lissy93/dashy/pull/38)
- Adds a new route, for the workspace view
- Builds the sidebar, which displays the users apps
- Loads the app into the workspace's main iframe when clicked
- Adds some collapsing functionality, better styles, subtle animations and theme support
## ✨ 1.1.6 - Implements Status Indicators, and Monitoring Functionality [PR #34](https://github.com/Lissy93/dashy/pull/34)
- Wrote a Node endpoint for pinging the users desired services
- Added status checking functionality in frontend
- Build small traffic-light component to display status of users services
- Adds animations, and handles errors
- Writes docs, and tests code
## ✨ 1.1.5 - Adds Authentication / Login Functionality [PR #32](https://github.com/Lissy93/dashy/pull/32)
- Enables the user to protect their dashboard behind a login screen
- Creates a Authentication handler to manage the hashing of passwords, and generation of a token
- Build a quick login form, where user can input username and password
- Adds a log out button
## 💄 1.1.4 - Support for Custom HTML Footer [PR #30](https://github.com/Lissy93/dashy/pull/30)
- Enables user to insert structure for the footer defined as HTML
## 🚀 1.1.3 - Adds Support for 1-Click Cloud Deployments [PR #29](https://github.com/Lissy93/dashy/pull/29)
- Support for 1-Click Deploy to Netlify
- Support for 1-Click Deploy to Heroku
## 🔧 1.1.2 - Docker Efficiency Improvements [PR #26](https://github.com/Lissy93/dashy/pull/26)
- Writes a Node health check script, and implements into the Docker container
- Changes default port in docker-compose, as 8080 is commonly used by other apps
- Adds the 1-Click deploy with PWD into the readme
- Updates dependencies
- Adds a getting started guide to the docs
- Adds splash screen for first load
- Deleted unused assets
- Makes linter run as a pre-commit hook
- Fixes lint errors in server.js and validate-config.js
## 🐛 1.1.1 - Bug Fixes [PR #20](https://github.com/Lissy93/dashy/pull/20) + [PR #21](https://github.com/Lissy93/dashy/pull/21)
- Adds issue template
- Bug fixes
- Improves github PR and issue templates
- Shortens readme file
- Adds documentation in the docs folder
- Fixes Layout tab not showing in portrait #19
- Improves mobile performance for both the settings, config and backup pop-ups
- Fixes issue where theme not applied on load when the settings are hidden
- Adds minimum dimensions to modalsShortens readme file
- Adds documentation in the docs folder
- Adds minimum dimensions to modals
## 🚑️ 1.1.0 - Hotfix [#18](https://github.com/Lissy93/dashy/pull/18)
- Implementing the JSON validator had actually broken the entire JSON editor
- Fixed it by remove explicit use of Ajv, and using a derivative instead
## 📝 1.0.5 - Documentation [PR #16](https://github.com/Lissy93/dashy/pull/16)
- Previously there was very little documentation, this release fixed that
- Wrote specific docs for:
- Getting Started
- Configuring
- Backup & Restore
- Theming
- Developing
## ✨ 1.0.0 - Implements Config Validation [PR #13](https://github.com/Lissy93/dashy/pull/13)
- Write a JSON schema for the conf.yml file
- Wrote a validation script to compare users config against schema
- Adds a formatter to print helpful messages about what needs fixing
- Implements validation process into build script
- Implements validation process into UI config configurator's validation
## 🔧 0.9.5 - Brand New Docker Container [PR #12](https://github.com/Lissy93/dashy/pull/12)
- With help from several users, a new container based on Alpine is released
- A sample Docker Compose script is also written, and docs are updated
- A 1-Click button for deploying to Play-with-Docker is added to the Readme
## ✨ 0.9.0 - Adds Hide Settings Functionality [PR #11](https://github.com/Lissy93/dashy/pull/11)
- Enables user to hide settings from UI
- Users preference is saved in local storage
- User can hide other structural elements of the UI from the config
## 💄 0.8.5 - Adds new Built-In Themes [PR #9](https://github.com/Lissy93/dashy/pull/9)
- Adds Minimal-Dark and Minimal-Light theme
- Adds Material-Dark and Material-Light theme
- Adds additional theme docs
- Adds option for sections to have items too
## ✨ 0.8.0 - Implements Custom CSS Editor [PR: #8](https://github.com/Lissy93/dashy/pull/8)
- Adds a page in the config menu
- Adds syntax highlighting, CSS validation and sanitization
- Saves users CSS, and applies styles on page load
## ✨ 0.7.5 - Adds Cloud Backup and Restore Feature [PR #6](https://github.com/Lissy93/dashy/pull/6)
- Creates a form for entering backup ID and decryption password
- Puts form in modal, and adds button to launch form, with custom icon
- Implemented the cryptography stuff for end-to-end data encryption
- Wrote and tested the backend, and deployed as a serverless function on CF workers
- On the frontend, users input is encrypted, and passed to backend cloud function
- Response from the backend is handles appropriately, and message displayed to the user
- Implements the restoring from server functionality, with data integrity checks
## ✨ 0.7.0 - Support for Custom Nav Links [PR #4](https://github.com/Lissy93/dashy/pull/4)
- User can add custom nav bar links from the Config Settings menu
- Better UI styling to the config menu
- New icons inside buttons
## ✨ 0.6.5 - UI Config Editor [PR #3](https://github.com/Lissy93/dashy/pull/3)
Adds the ability for the user to edit their configuration directly from the UI
- Edit all section and item data using a rich JSON editor
- Download/ backup conf.yml directly from the UI
- Edit site meta data: title, description, footer, etc
- Reset all locally stored data to the initial state
- Also includes a new toast component, for subtle notifications
## ✨ 0.6.0 - Navbar, Footer and Background Image
- Adds option for a custom full-size background image
- Made footer customizable
- Fixes error being thrown when navbar links are empty
## ⚡️ 0.5.5 - Improved Theming
- Makes more specific color variables, which inherit base vars
- Makes it possible for users to write their own theme
- Fix some color edge cases
- Adds docs for theming
## ✨ 0.5.0 - Theme Support
- Converts all SCSS variables to CSS variables
- Implements theme switching functionality
- Adds a dropdown menu, enabling user to select theme
- Adds an initial theme option to `appConfig.theme`
- Saves selected theme to local storage
- Wrote a ton of color themes
## ✨ 0.4.5 - Keyboard Navigation
- Implements arrow key navigation
## ✨ 0.4.0 - Font Awesome Support
- Adds support for Font-Awesome icons
- Auto-loads font-awesome only when needed
- Adds support for SVG icons
## ✨ 0.3.5 - Opening Method
- Shows opening method on hover
- Opening method can be specified in config, as `item[n].target`
## 🔨 0.3.0 - Docker
- Writes a Dockerfile
## 🎨 0.2.5 - Code Quality, Docs and UI
- Huge code quality overhaul, now uses AirBnB style ESLint
- Adds in-code docs, removes unneeded code, moves reusable helpers into utils dir
- Adds a readme, records a demo gif and adds some basic deployment docs
- Removes dependencies which are not 100% necessary
## ✨ 0.2.0 - Collapsible Sections
- Implements collapsing functionality, for less used or very long sections
- Sections can read default state from `section[n].collapsed` within config
- After change, state of each section is stored in local storage
## ⚡️ 0.1.5 - Search and Navigation
- Improves instant search functionality
- Implements keyboard navigation for selecting items
- Launch selected item with enter, or Ctrl + Enter to open in new tab
## 🎉 0.1.0 - Init
Project started. Forked from [Lissy93/Dash](https://github.com/Lissy93/dash)

View File

@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
alicia@omg.lol.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -1,228 +0,0 @@
# Configuring
All app configuration is specified in [`/public/conf.yml`](https://github.com/Lissy93/dashy/blob/master/public/conf.yml) which is in [YAML Format](https://yaml.org/) format.
Tips:
- You may find it helpful to look at some sample config files to get you started, a collection of which can be found [here](https://gist.github.com/Lissy93/000f712a5ce98f212817d20bc16bab10)
- You can check that your config file fits the schema, by running `yarn validate-config`
- After modifying your config, the app needs to be recompiled, by running `yarn build` - this happens automatically whilst the app is running if you're using Docker
- It is recommended to make and keep a backup of your config file. You can download your current config through the UI either from the Config menu, or using the `/download` endpoint. Alternatively, you can use the [Cloud Backup](/docs/backup-restore) feature.
- The config can also be modified directly through the UI, validated and written to the conf.yml file.
- All fields are optional, unless otherwise stated.
### About YAML
If you're new to YAML, it's pretty straight-forward. The format is exactly the same as that of JSON, but instead of using curly braces, structure is denoted using whitespace. This [quick guide](https://linuxhandbook.com/yaml-basics/) should get you up to speed in a few minutes, for more advanced topics take a look at this [Wikipedia article](https://en.wikipedia.org/wiki/YAML).
### Config Saving Methods
When updating the config through the JSON editor in the UI, you have two save options: **Local** or **Write to Disk**.
- Changes saved locally will only be applied to the current user through the browser, and will not apply to other instances - you either need to use the cloud sync feature, or manually update the conf.yml file.
- On the other-hand, if you choose to write changes to disk, then your main `conf.yml` file will be updated, and changes will be applied to all users, and visible across all devices. For this functionality to work, you must be running Dashy with using the Docker container, or the Node server. A backup of your current configuration will also be saved in the same directory.
### Preventing Changes being Written to Disk
To disallow any changes from being written to disk via the UI config editor, set `appConfig.allowConfigEdit: false`. If you are using users, and have setup `auth` within Dashy, then only users with `type: admin` will be able to write config changes to disk.
### Top-Level Fields
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`pageInfo`** | `object` | Required | Basic meta data like title, description, nav bar links, footer text. See [`pageInfo`](#pageinfo)
**`appConfig`** | `object` | _Optional_ | Settings related to how the app functions, including API keys and global styles. See [`appConfig`](#appconfig-optional)
**`sections`** | `array` | Required | An array of sections, each containing an array of items, which will be displayed as links. See [`section`](#section)
**[⬆️ Back to Top](#)**
### `PageInfo`
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`title`** | `string` | Required | Your dashboard title, displayed in the header and browser tab
**`description`** | `string` | _Optional_ | Description of your dashboard, also displayed as a subtitle
**`navLinks`** | `array` | _Optional_ | Optional list of a maximum of 6 links, which will be displayed in the navigation bar. See [`navLinks`](#pageinfonavlinks-optional)
**`footerText`** | `string` | _Optional_ | Text to display in the footer (note that this will override the default footer content). This can also include HTML and inline CSS
**`logo`** | `string` | _Optional_ | The path to an image to display in the header (to the right of the title). This can be either local, where `/` is the root of `./public`, or any remote image, such as `https://i.ibb.co/yhbt6CY/dashy.png`. It's recommended to scale your image down, so that it doesn't impact load times
**[⬆️ Back to Top](#)**
### `pageInfo.navLinks` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`title`** | `string` | Required | The text to display on the link button
**`path`** | `string` | Required | The URL to navigate to when clicked. Can be relative (e.g. `/about`) or absolute (e.g. `https://example.com` or `http://192.168.1.1`)
**[⬆️ Back to Top](#)**
### `appConfig` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`language`** | `string` | _Optional_ | The 2 (or 4-digit) [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, e.g. `en` or `en-GB`. This must be a language that the app has already been [translated](https://github.com/Lissy93/dashy/tree/master/src/assets/locales) into. If your language is unavailable, Dashy will fallback to English. By default Dashy will attempt to auto-detect your language, although this may not work on some privacy browsers.
**`startingView`** | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default`
**`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting `statusCheck` under each item. Defaults to `false`
**`statusCheckInterval`** | `boolean` | _Optional_ | The number of seconds between checks. If set to `0` then service will only be checked on initial page load, which is usually the desired functionality. If value is less than `10` you may experience a hit in performance. Defaults to `0`
**`backgroundImg`** | `string` | _Optional_ | Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
**`enableFontAwesome`** | `boolean` | _Optional_ | Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
**`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`)
**`faviconApi`** | `enum` | _Optional_ | Only applicable if you are using favicons for item icons. Specifies which service to use to resolve favicons. Set to `local` to do this locally, without using an API. Services running locally will use this option always. Available options are: `local`, `faviconkit`, `google`, `clearbit`, `webmasterapi` and `allesedv`. Defaults to `faviconkit`. See [Icons](/docs/icons#favicons) for more info
**`auth`** | `object` | _Optional_ | All settings relating to user authentication. See [`auth`](#appconfigauth-optional)
**`layout`** | `enum` | _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.
**`iconSize`** | `enum` | _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.
**`theme`** | `string` | _Optional_ | The default theme for first load (you can change this later from the UI)
**`cssThemes`** | `string[]` | _Optional_ | An array of custom theme names which can be used in the theme switcher dropdown
**`customColors`** | `object`| _Optional_ | Enables you to apply a custom color palette to any given theme. Use the theme name (lowercase) as the key, for an object including key-value-pairs, with the color variable name as keys, and 6-digit hex code as value. See [Theming](/docs/theming#modifying-theme-colors) for more info
**`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
**`customCss`** | `string` | _Optional_ | Raw CSS that will be applied to the page. This can also be set from the UI. Please minify it first.
**`hideComponents`** | `object` | _Optional_ | A list of key page components (header, footer, search, settings, etc) that are present by default, but can be removed using this option. See [`appConfig.hideComponents`](#appconfighideComponents-optional)
**`enableMultiTasking`** | `boolean` | _Optional_ | If set to true, will keep apps open in the background when in the workspace view. Useful for quickly switching between multiple sites, and preserving their state, but comes at the cost of performance.
**`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.
**`enableErrorReporting`** | `boolean` | _Optional_ | Enable reporting of unexpected errors and crashes. This is off by default, and **no data will ever be captured unless you explicitly enable it**. Turning on error reporting helps previously unknown bugs get discovered and fixed. Dashy uses [Sentry](https://github.com/getsentry/sentry) for error reporting. Defaults to `false`.
**`sentryDsn`** | `boolean` | _Optional_ | If you need to monitor errors in your instance, then you can use Sentry to collect and process bug reports. Sentry can be self-hosted, or used as SaaS, once your instance is setup, then all you need to do is pass in the DSN here, and enable error reporting. You can learn more on the [Sentry DSN Docs](https://docs.sentry.io/product/sentry-basics/dsn-explainer/). Note that this will only ever be used if `enableErrorReporting` is explicitly enabled.
**`disableUpdateChecks`** | `boolean` | _Optional_ | If set to true, Dashy will not check for updates. Defaults to `false`.
**`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.
**`disableContextMenu`** | `boolean` | _Optional_ | If set to `true`, the custom right-click context menu will be disabled. Defaults to `false`.
**[⬆️ Back to Top](#)**
### `appConfig.auth` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`users`** | `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. See [`appConfig.auth.users`](#appconfigauthusers-optional). <br />**Note** this method of authentication is handled on the client side, so for security critical situations, it is recommended to use an [alternate authentication method](/docs/authentication#alternative-authentication-methods).
**`enableKeycloak`** | `object` | _Optional_ | If set to `true`, then authentication using Keycloak will be anabled. Note that you need to have an instance running, and have also configured `auth.keycloak`. Defaults to `false`
**`keycloak`** | `boolean` | _Optional_ | Config options to point Dashy to your Keycloak server. Requires `enableKeycloak: true`. See [`auth.keycloak`](#appconfigauthkeycloak-optional) for more info
**`enableGuestAccess`** | `boolean` | _Optional_ | When set to `true`, an unauthenticated user will be able to access the dashboard, with read-only access, without having to login. Requires `auth.users` to be configured. Defaults to `false`.
For more info, see the **[Authentication Docs](/docs/authentication)**
**[⬆️ Back to Top](#)**
### `appConfig.auth.users` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`user`** | `string` | Required | Username to log in with
**`hash`** | `string` | Required | A SHA-256 hashed password
**`type`** | `string` | _Optional_ | The user type, either admin or normal
**[⬆️ Back to Top](#)**
### `appConfig.auth.keycloak` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`serverUrl`** | `string` | Required | The URL (or URL/ IP + Port) where your keycloak server is running
**`realm`** | `string` | Required | The name of the realm (must already be created) that you want to use
**`clientId`** | `string` | Required | The Client ID of the client you created for use with Dashy
**[⬆️ Back to Top](#)**
### `appConfig.hideComponents` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`hideHeading`** | `boolean` | _Optional_ | If set to `true`, the page title & sub-title will not be visible. Defaults to `false`
**`hideNav`** | `boolean` | _Optional_ | If set to `true`, the navigation menu will not be visible. Defaults to `false`
**`hideSearch`** | `boolean` | _Optional_ | If set to `true`, the search bar will not be visible. Defaults to `false`
**`hideSettings`** | `boolean` | _Optional_ | If set to `true`, the settings menu will not be visible. Defaults to `false`
**`hideFooter`** | `boolean` | _Optional_ | If set to `true`, the footer will not be visible. Defaults to `false`
**`hideSplashScreen`** | `boolean` | _Optional_ | If set to `true`, splash screen will not be visible while the app loads. Defaults to `true` (except on first load, when the loading screen is always shown)
**[⬆️ Back to Top](#)**
### `section`
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`name`** | `string` | Required | The title for the section
**`icon`** | `string` | _Optional_ | An single icon to be displayed next to the title. See [`section.icon`](#sectionicon-and-sectionitemicon)
**`items`** | `array` | Required | An array of items to be displayed within the section. See [`item`](#sectionitem)
**`displayData`** | `object` | _Optional_ | Meta-data to optionally overide display settings for a given section. See [`displayData`](#sectiondisplaydata-optional)
**[⬆️ Back to Top](#)**
### `section.item`
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`title`** | `string` | Required | The text to display/ title of a given item. Max length `18`
**`description`** | `string` | _Optional_ | Additional info about an item, which is shown in the tooltip on hover, or visible on large tiles
**`url`** | `string` | Required | The URL / location of web address for when the item is clicked
**`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)
**`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.
**`hotkey`** | `number` | _Optional_ | Give frequently opened applications a numeric hotkey, between `0 - 9`. You can then just press that key to launch that application.
**`tags`** | `string[]` | _Optional_ | A list of tags, which can be used for improved search
**`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`
**`statusCheckUrl`** | `string` | _Optional_ | If you've enabled `statusCheck`, and want to use a different URL to what is defined under the item, then specify it here
**`statusCheckHeaders`** | `object` | _Optional_ | If you're endpoint requires any specific headers for the status checking, then define them here
**`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
**`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
**`provider`** | `string` | _Optional_ | The name of the provider for a given service, useful for when including hosted apps. In some themes, this is visible under the item name
**[⬆️ Back to Top](#)**
### `section.displayData` _(optional)_
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`collapsed`** | `boolean` | _Optional_ | If true, the section will be collapsed initially, and will need to be clicked to open. Useful for less regularly used, or very long sections. Defaults to `false`
**`color`** | `string` | _Optional_ | A custom accent color for the section, as a hex code or HTML color (e.g. `#fff`)
**`customStyles`** | `string` | _Optional_ | Custom CSS properties that should be applied to that section, e.g. `border: 2px dashed #ff0000;`
**`itemSize`** | `string` | _Optional_ | Specify the size for items within this group, either `small`, `medium` or `large`. Note that this will overide any settings specified through the UI
**`rows`** | `number` | _Optional_ | Height of the section, specified as the number of rows it should span vertically, e.g. `2`. Defaults to `1`. Max is `5`.
**`cols`** | `number` | _Optional_ | Width of the section, specified as the number of columns the section should span horizontally, e.g. `2`. Defaults to `1`. Max is `5`.
**`sectionLayout`** | `string` | _Optional_ | Specify which CSS layout will be used to responsivley place items. Can be either `auto` (which uses flex layout), or `grid`. If `grid` is selected, then `itemCountX` and `itemCountY` may also be set. Defaults to `auto`
**`itemCountX`** | `number` | _Optional_ | The number of items to display per row / horizontally. If not set, it will be calculated automatically based on available space. Can only be set if `sectionLayout` is set to `grid`. Must be a whole number between `1` and `12`
**`itemCountY`** | `number` | _Optional_ | The number of items to display per column / vertically. If not set, it will be calculated automatically based on available space. If `itemCountX` is set, then `itemCountY` can be calculated automatically. Can only be set if `sectionLayout` is set to `grid`. Must be a whole number between `1` and `12`
**`hideForUsers`** | `string[]` | _Optional_ | Current section will be visible to all users, except for those specified in this list
**`showForUsers`** | `string[]` | _Optional_ | Current section will be hidden from all users, except for those specified in this list
**`hideForGuests`** | `boolean` | _Optional_ | Current section will be visible for logged in users, but not for guests (see `appConfig.enableGuestAccess`). Defaults to `false`
**[⬆️ Back to Top](#)**
### `section.icon` and `section.item.icon`
**Field** | **Type** | **Required**| **Description**
--- | --- | --- | ---
**`icon`** | `string` | _Optional_ | The icon for a given item or section. Can be a font-awesome icon, favicon, remote URL or local URL. If set to `favicon`, the icon will be automatically fetched from the items website URL. To use font-awesome, specify the category, followed by the icon name, e.g. `fas fa-rocket`, `fab fa-monero` or `fal fa-duck` - note that to use pro icons, you mut specify `appConfig.fontAwesomeKey`. Similarly, you can also use [simple-icons](https://simpleicons.org/) by setting icon to `si-[icon-name]` or [material-design-icons](https://dev.materialdesignicons.com/icons) by setting icon to `mdi-[icon-name]`. If set to `generative`, then a unique icon is generated from the apps URL or IP. You can also use hosted any by specifying it's URL, e.g. `https://i.ibb.co/710B3Yc/space-invader-x256.png`. To use a local image, first store it in `./public/item-icons/` (or `-v /app/public/item-icons/` in Docker) , and reference it by name and extension - e.g. set `image.png` to use `./public/item-icon/image.png`, you can also use sub-folders if you have a lot of icons, to keep them organised.
**[⬆️ Back to Top](#)**
### Example
```yaml
---
pageInfo:
title: Home Lab
sections: # An array of sections
- name: Section 1 - Getting Started
items: # An array of items
- title: GitHub
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
description: A live demo
icon: far fa-rocket
url: https://dashy-demo-1.netlify.app
- name: Section 2 - Local Services
items:
- title: Firewall
icon: favicon
url: http://192.168.1.1/
- title: Game Server
icon: https://i.ibb.co/710B3Yc/space-invader-x256.png
url: http://192.168.130.1/
```
For more example config files, see: [this gist](https://gist.github.com/Lissy93/000f712a5ce98f212817d20bc16bab10)
If you need any help, feel free to [Raise an Issue](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) or [Start a Discussion](https://github.com/Lissy93/dashy/discussions)
Happy Configuring 🤓🔧
**[⬆️ Back to Top](#)**

View File

@ -1,105 +0,0 @@
# Contributing
First off, thank you for considering contributing towards Dashy! 🙌
There are several ways that you can help out (but don't feel you have to).
Any contributions, however small will always be very much appreciated, and you will be appropriately credited in the readme - huge thank you to [everyone who has helped](/docs/credits) so far 💞
## Submit a PR
Contributing to the code or documentation is super helpful. You can fix a bug, add a new feature or improve an existing one. I've written [several guides](https://github.com/Lissy93/dashy/blob/master/docs/development-guides) to help you get started. For setting up the development environment, outline of the standards, and understanding the PR flow, see the [Development Docs](https://github.com/Lissy93/dashy/blob/master/docs/development). I've tried to keep the code neat and documentation thorough, so understanding what everything does should be fairly straight forward, but feel free to ask if you have any questions.
## Add Translations
If you speak another language, then adding translations would be really helpful, and you will be credited in the readme for your work. Multi-language support makes Dashy accessible for non-English speakers, which I feel is important. This is a very quick and easy task, as all application text is located in [`locales/en.json`](https://github.com/Lissy93/dashy/blob/master/src/assets/locales/en.json), so adding a new language is as simple as copying this file and translating the values. You don't have to translate it all, as any missing attributes will just fallback to English. For a full tutorial, see the [Multi-Language Support Docs](https://github.com/Lissy93/dashy/blob/master/docs/multi-language-support).
## Take a 2-minute survey
Help improve Dashy by taking a very short, 6-question survey. This will give me a better understanding of what is important to you, so that I can make Dashy better in the future :)
[![Take the Survey](https://img.shields.io/badge/Take_the-Survey-%231a86fd?style=for-the-badge&logo=buddy)](https://n9fy6xak9yd.typeform.com/to/gl0L68ou)
## Share your dashboard
Dashy now has a [Showcase](https://github.com/Lissy93/dashy/blob/master/docs/showcase#dashy-showcase-) where you can show off a screenshot of your dashboard, and get inspiration from other users. I also really enjoy seeing how people are using Dashy. To [submit your dashboard](https://github.com/Lissy93/dashy/blob/master/docs/showcase#submitting-your-dashboard), please either open a PR or raise an issue.
## Improve the Docs
Found a typo, or something that isn't as clear as it could be? Maybe I've missed something off altogether, or you hit a roadblock that took you a while to figure out. Submitting a pull request to add to or improve the documentation will help future users get Dashy up and running more easily.
All content is located either in the [`./README.md`](/README) or [`/docs/`](/docs) directory, and synced to the Wiki and website using a GH [action](/actions/workflows/wiki-sync.yml).
## Raise a bug
If you've found a bug, then please do raise it as an issue. This will help me know if there's something that needs fixing. Try and include as much detail as possible, such as your environment, steps to reproduce, any console output and maybe an example screenshot or recording if necessary.
[![Raise a Bug](https://img.shields.io/badge/Raise_a-Bug-%23dc2d76?style=for-the-badge&logo=dependabot)](https://github.com/Lissy93/dashy/issues/new?assignees=lissy93&labels=%F0%9F%90%9B+Bug&template=bug.yml&title=%5BBUG%5D+%3Ctitle%3E)
## Join the discussion
I've enabled the discussion feature on GitHub, here you can share tips and tricks, useful information, or your dashboard. You can also ask questions, and offer basic support to other users.
[![Join the Discussion on GitHub](https://img.shields.io/badge/Join_the-Discussion-%23ffd000?style=for-the-badge&logo=livechat)](https://github.com/Lissy93/dashy/discussions)
## Spread the word
Dashy is still a relatively young project, and as such not many people know of it. It would be great to see more users, and so it would be awesome if you could consider sharing on social platforms.
[![Share Dashy on Mastodon](https://img.shields.io/badge/Share-Mastodon-%232b90d9?style=for-the-badge&logo=mastodon)](https://mastodon.social/?text=Check%20out%20Dashy%2C%20the%20privacy-friendly%2C%20self-hosted%20startpage%20for%20organizing%20your%20life%3A%20https%3A%2F%2Fgithub.com%2FLissy93%2Fdashy%20-%20By%20%40lissy93%40mastodon.social)
[![Share Dashy on Reddit](https://img.shields.io/badge/Share-Reddit-%23FF5700?style=for-the-badge&logo=reddit)](http://www.reddit.com/submit?url=https://github.com/Lissy93/dashy&title=Dashy%20-%20The%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80)
[![Share Dashy on Twitter](https://img.shields.io/badge/Share-Twitter-%231DA1F2?style=for-the-badge&logo=twitter)](https://twitter.com/intent/tweet?url=https://github.com/lissy93/dashy&text=Check%20out%20Dashy%20by%20@Lissy_Sykes,%20the%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80)
[![Share Dashy on Facebook](https://img.shields.io/badge/Share-Facebook-%234267B2?style=for-the-badge&logo=facebook)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/lissy93/dashy)
[![Share Dashy on LinkedIn](https://img.shields.io/badge/Share-LinkedIn-%230077b5?style=for-the-badge&logo=linkedin)](https://www.linkedin.com/shareArticle?mini=true&url=https://github.com/lissy93/dashy)
[![Share Dashy on Pinterest](https://img.shields.io/badge/Share-Pinterest-%23E60023?style=for-the-badge&logo=pinterest)](https://pinterest.com/pin/create/button/?url=https://github.com/lissy93/dashy&media=https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/1-home-lab-material.png&description=Check%20out%20Dashy,%20the%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80)
[![Share Dashy on VK](https://img.shields.io/badge/Share-VK-%234C75A3?style=for-the-badge&logo=vk)](https://vk.com/share.php?url=https%3A%2F%2Fgithub.com%2Flissy93%2Fdashy%2F&title=Check%20out%20Dashy%20-%20The%20Self-Hosted%20Dashboard%20for%20your%20Homelab%20%F0%9F%9A%80)
[![Share Dashy via Viber](https://img.shields.io/badge/Share-Viber-%238176d6?style=for-the-badge&logo=viber)](viber://forward?text=https%3A%2F%2Fgithub.com%2Flissy93%2Fdashy%0ACheck%20out%20Dashy%2C%20the%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80)
[![Share Dashy via Telegram](https://img.shields.io/badge/Share-Telegram-%230088cc?style=for-the-badge&logo=telegram)](https://t.me/share/url?url=https%3A%2F%2Fgithub.com%2Flissy93%2Fdashy&text=Check%20out%20Dashy%2C%20the%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80)
[![Share Dashy via Email](https://img.shields.io/badge/Share-Email-%238A90C7?style=for-the-badge&logo=protonmail)](mailto:info@example.com?&subject=Check%20out%20Dashy%20-%20The%20self-hosted%20dashboard%20for%20your%20homelab%20%F0%9F%9A%80&cc=&bcc=&body=https://github.com/lissy93/dashy)
## Star, Upvote or Leave a Review
Dashy is on the following platforms, and if you could spare a few seconds to give it an upvote or review, this will also help new users find it.
[![ProductHunt](https://img.shields.io/badge/Review-ProductHunt-%23b74424?style=for-the-badge&logo=producthunt)](https://www.producthunt.com/posts/dashy)
[![AlternativeTo](https://img.shields.io/badge/Review-AlternativeTo-%235581a6?style=for-the-badge&logo=abletonlive)](https://alternativeto.net/software/dashy/about/)
[![Slant](https://img.shields.io/badge/Review-Slant-%2346a1df?style=for-the-badge&logo=capacitor)](https://www.slant.co/improve/topics/27783/viewpoints/1/~self-hosted-homelab-startpage~dashy)
[![Star on GitHub](https://img.shields.io/github/stars/Lissy93/Dashy?color=ba96d6&label=Star%20-%20GitHub&logo=github&style=for-the-badge)](https://github.com/Lissy93/dashy/stargazers)
[![Star on DockerHub](https://img.shields.io/docker/stars/lissy93/dashy?color=4cb6e0&label=Star%20-%20Docker&logo=docker&style=for-the-badge)](https://hub.docker.com/r/lissy93/dashy)
## Make a small donation
Please only do this is you can definitely afford to. Don't feel any pressure to donate anything, as Dashy and my other projects will always be 100% free, for everyone, for ever.
[![Sponsor Lissy93 on GitHub](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/sponsor-button.svg)](https://github.com/sponsors/Lissy93)
Sponsoring will give you several perks, from $1 / £0.70 per month, as well as a sponsor badge on your profile, you can also be credited on the readme, with a link to your website/ profile/ socials, get priority support, have your feature ideas implemented, plus lots more. For more info, see [@Lissy93's Sponsor Page](https://github.com/sponsors/Lissy93).
## Request a feature via BountySource
BountySource is a platform for sponsoring the development of certain features on open source projects. If there is a feature you'd like implemented into Dashy, but either isn't high enough priority or is deemed to be more work than it's worth, then you can instead contribute a bounty towards it's development. You won't pay a penny until your proposal is fully built, and you are satisfied with the result. This helps support the developers, and makes Dashy better for everyone.
[![Request a Feature on BountySource](https://img.shields.io/badge/BountySource-Dashy-%23F67909?style=for-the-badge&logo=openbugbounty)](https://www.bountysource.com/teams/dashy)
## Enable Anonymous Bug Reports
[Sentry](https://github.com/getsentry/sentry) is an open source error tracking and performance monitoring tool, which enables the identification any errors which occur in the production app (only if you enable it). It helps me to discover bugs I was unaware of, and then fix them, in order to make Dashy more reliable long term. This is a simple, yet really helpful step you can take to help improve Dashy.
To enable error reporting:
```yaml
appConfig:
enableErrorReporting: true
```
All reporting is **disabled** by default, and no data will ever be sent to any external endpoint without your explicit consent. In fact, the error tracking package will not even be imported unless you have actively enabled it. All statistics are anonomized and stored securely. For more about privacy and security, see the [Sentry Docs](https://sentry.io/security/).
## Follow for More
If you've enjoyed Dashy, you can follow the me to get updates about other projects that I am working on.
[![Alicia Sykes on Twitter](https://img.shields.io/twitter/follow/Lissy_Sykes?style=social&logo=twitter)](https://twitter.com/Lissy_Sykes)
[![Alicia Sykes on GitHub](https://img.shields.io/github/followers/lissy93?label=Lissy93&style=social)](https://github.com/Lissy93)
[![Alicia Sykes on Mastodon](https://img.shields.io/mastodon/follow/1032965?domain=https%3A%2F%2Fmastodon.social)](https://mastodon.social/web/accounts/1032965)
[![Alicia Sykes on Keybase](https://img.shields.io/badge/aliciasykes--lightgrey?style=social&logo=Keybase)](https://keybase.io/aliciasykes)
[![Alicia Sykes's PGP](https://img.shields.io/badge/PGP--lightgrey?style=social&logo=Let%E2%80%99s%20Encrypt)](https://keybase.io/aliciasykes/pgp_keys.asc)
[![Alicia Sykes's Website](https://img.shields.io/badge/aliciasykes.com--lightgrey?style=social&logo=Tencent%20QQ)](https://aliciasykes.com)
[![Alicia Sykes's Blog](https://img.shields.io/badge/Blog--lightgrey?style=social&logo=micro.blog)](https://notes.aliciasykes.com/)
If you like, you could also consider [subscribing to my mailing list](https://notes.aliciasykes.com/subscribe) for very occasional blog post updates, or even [nominating me (`@lissy93`)](https://stars.github.com/nominate/) on the GitHub Star Programme.
---
### Contributors
For a full list of Dashy's contributors, see the [Credits Page](/docs/credits)
![Auto-generated contributors](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/CONTRIBUTORS.svg)
### Star-Gazers Over Time
![Stargazers](https://starchart.cc/Lissy93/dashy.svg)

View File

@ -1,196 +0,0 @@
# Credits
## Sponsors
<table>
<tr>
<td align="center">
<a href="https://github.com/Robert-Ernst">
<img src="https://avatars.githubusercontent.com/u/9050259?u=7253b4063f1ffe3b5a894263c8b2056151802508&v=4" width="80;" alt="Robert-Ernst"/>
<br />
<sub><b>Robert Ernst</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/swcarlosrj">
<img src="https://avatars.githubusercontent.com/u/9881700?u=c92e4a0ccc0bff241e50582bce914b179b6d89b6&v=4" width="80;" alt="swcarlosrj"/>
<br />
<sub><b>Carlos Rufo</b></sub>
</a>
</td></tr>
</table>
## Contributors
<table>
<tr>
<td align="center">
<a href="https://github.com/Lissy93">
<img src="https://avatars.githubusercontent.com/u/1862727?v=4" width="80;" alt="Lissy93"/>
<br />
<sub><b>Alicia Sykes</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/EVOTk">
<img src="https://avatars.githubusercontent.com/u/45015615?v=4" width="80;" alt="EVOTk"/>
<br />
<sub><b>EVOTk</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/evroon">
<img src="https://avatars.githubusercontent.com/u/11857441?v=4" width="80;" alt="evroon"/>
<br />
<sub><b>Erik Vroon</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/snyk-bot">
<img src="https://avatars.githubusercontent.com/u/19733683?v=4" width="80;" alt="snyk-bot"/>
<br />
<sub><b>Snyk Bot</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/onedr0p">
<img src="https://avatars.githubusercontent.com/u/213795?v=4" width="80;" alt="onedr0p"/>
<br />
<sub><b>ᗪєνιη ᗷυнʟ</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/UrekD">
<img src="https://avatars.githubusercontent.com/u/38784343?v=4" width="80;" alt="UrekD"/>
<br />
<sub><b>UrekD</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/BeginCI">
<img src="https://avatars.githubusercontent.com/u/57495754?v=4" width="80;" alt="BeginCI"/>
<br />
<sub><b>Begin</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/deepsourcebot">
<img src="https://avatars.githubusercontent.com/u/60907429?v=4" width="80;" alt="deepsourcebot"/>
<br />
<sub><b>DeepSource Bot</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/turnrye">
<img src="https://avatars.githubusercontent.com/u/701035?v=4" width="80;" alt="turnrye"/>
<br />
<sub><b>Ryan Turner</b></sub>
</a>
</td></tr>
</table>
## Helpful Users
<table>
<tr>
<td align="center">
<a href="https://github.com/evotk">
<img src="https://avatars.githubusercontent.com/u/45015615?v=4" width="80;" alt="evotk"/>
<br />
<sub><b>Evotk</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/shadowking001">
<img src="https://avatars.githubusercontent.com/u/43928955?v=4" width="80;" alt="shadowking001"/>
<br />
<sub><b>LawrenceP.</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/turnrye">
<img src="https://avatars.githubusercontent.com/u/701035?v=4" width="80;" alt="turnrye"/>
<br />
<sub><b>Ryan Turner</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/robert-ernst">
<img src="https://avatars.githubusercontent.com/u/9050259?v=4" width="80;" alt="robert-ernst"/>
<br />
<sub><b>Robert Ernst</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/milesteg1">
<img src="https://avatars.githubusercontent.com/u/29298312?v=4" width="80;" alt="milesteg1"/>
<br />
<sub><b>Milesteg1</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/niklashere">
<img src="https://avatars.githubusercontent.com/u/32072214?v=4" width="80;" alt="niklashere"/>
<br />
<sub><b>Niklas</b></sub>
</a>
</td></tr>
</table>
## Bots
<table>
<tr>
<td align="center">
<a href="https://github.com/liss-bot">
<img src="https://avatars.githubusercontent.com/u/87835202?v=4" width="80;" alt="liss-bot"/>
<br />
<sub><b>Alicia Bot</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/snyk-bot">
<img src="https://avatars.githubusercontent.com/u/19733683?v=4" width="80;" alt="snyk-bot"/>
<br />
<sub><b>Snyk Bot</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/github-actions[bot]">
<img src="https://avatars.githubusercontent.com/in/15368?v=4" width="80;" alt="github-actions[bot]"/>
<br />
<sub><b>github-actions[bot]</b></sub>
</a>
</td></tr>
</table>
## Dependencies 🔗
This app definitely wouldn't have been quite so possible without the making use of the following package and components. Full credit and big kudos to their respective authors, who've done an amazing job in building and maintaining them. For a full breakdown of dependency licenses, please see [Legal](https://github.com/Lissy93/dashy/blob/master/.github/LEGAL)
##### Core
At it's core, the application uses [Vue.js](https://github.com/vuejs/vue), as well as it's services. Styling is done with [SCSS](https://github.com/sass/sass), JavaScript is currently [Babel](https://github.com/babel/babel), (but I am in the process of converting to [TypeScript](https://github.com/Microsoft/TypeScript)). Linting is done with [ESLint](https://github.com/eslint/eslint) and [Prettier](https://prettier.io/), both following the [AirBnB Styleguide](https://github.com/airbnb/javascript). The config is defined in [YAML](https://github.com/yaml/yaml), and there is a simple [Node.js](https://github.com/nodejs/node) server to serve up the static app and the optional API endpoints.
##### Utilities
- [`crypto-js`](https://github.com/brix/crypto-js) - Encryption implementations by @evanvosberg and community `MIT`
- [`axios`](https://github.com/axios/axios) - Promise based HTTP client by @mzabriskie and community `MIT`
- [`ajv`](https://github.com/ajv-validator/ajv) - JSON schema Validator by @epoberezkin and community `MIT`
- [`vue-i18n`](https://github.com/kazupon/vue-i18n) - Internationalization plugin by @kazupon and community `MIT`
##### Frontend Components
- [`vue-select`](https://github.com/sagalbot/vue-select) - Dropdown component by @sagalbot `MIT`
- [`vue-js-modal`](https://github.com/euvl/vue-js-modal) - Modal component by @euvl `MIT`
- [`v-tooltip`](https://github.com/Akryum/v-tooltip) - Tooltip component by @Akryum `MIT`
- [`vue-material-tabs`](https://github.com/jairoblatt/vue-material-tabs) - Tab view component by @jairoblatt `MIT`
- [`VJsoneditor`](https://github.com/yansenlei/VJsoneditor) - Interactive JSON editor component by @yansenlei `MIT`
- Forked from [`JsonEditor`](https://github.com/josdejong/jsoneditor) by @josdejong `Apache-2.0 License`
- [`vue-toasted`](https://github.com/shakee93/vue-toasted) - Toast notification component by @shakee93 `MIT`
- [`vue-swatches`](https://github.com/saintplay/vue-swatches) - Color palete picker by @saintplay `MIT`
##### Backup & Sync Server
Although the app is purely frontend, there is an optional cloud backup and restore feature. This is built as a serverless function on [Cloudflare workers](https://workers.cloudflare.com/) using [KV](https://developers.cloudflare.com/workers/runtime-apis/kv) and [web crypto](https://developers.cloudflare.com/workers/runtime-apis/web-crypto)
##### External Services
The 1-Click deploy demo uses [Play-with-Docker Labs](https://play-with-docker.com/). Code is hosted on [GitHub](https://github.com), Docker images are hosted on [DockerHub](https://hub.docker.com/), and the demos are hosted on [Netlify](https://www.netlify.com/).
---
> This page is auto-generated, using [contribute-list](https://github.com/marketplace/actions/contribute-list) by @akhilmhdh.

View File

@ -1,245 +0,0 @@
# Deployment
Welcome to Dashy, so glad you're here :) Deployment is super easy, and there are several methods available depending on what type of system you're using. If you're self-hosting, then deploying with Docker (or similar container engine) is the recommended approach.
#### Quick Start
If you want to skip the fuss, and [get straight down to it](/docs/quick-start), then you can spin up a new instance of Dashy by running:
```
docker run -p 8080:80 lissy93/dashy
```
See [Management Docs](/docs/management) for info about securing, monitoring, updating, health checks, auto starting, web server configuration, etc
Once you've got Dashy up and running, you'll want to configure it with your own content, for this you can reference the [configuring docs](/docs/configuring).
## Deployment Methods
- [Deploy with Docker](#deploy-with-docker)
- [Using Docker Compose](#using-docker-compose)
- [Build from Source](#build-from-source)
- [Hosting with CDN](#hosting-with-cdn)
- [Run as executable](#run-as-executable)
- [Install with NPM](#install-with-npm)
- [Deploy to cloud service](#deploy-to-cloud-service)
- [Use managed instance](#use-managed-instance)
### Deploy with Docker
**Container Info**: [
![Docker Supported Architecture](https://img.shields.io/badge/Architectures-amd64%20|%20arm32v7%20|%20arm64v8-6ba6e5)
![Docker Base Image](https://img.shields.io/badge/Base_Image-Alpine_3.14-6ba6e5)
![Docker Hosted on](https://img.shields.io/badge/Hosted_on-DockerHub-6ba6e5)
](https://hub.docker.com/r/lissy93/dashy)
**Status**: [
![Docker Build Status](https://img.shields.io/docker/cloud/build/lissy93/dashy?label=Docker%20Build)
![Docker Pulls](https://img.shields.io/docker/pulls/lissy93/dashy?color=ecb2f7)
![Docker Stars](https://img.shields.io/docker/stars/lissy93/dashy?color=f7f754&label=Docker%20Stars)
![Docker Image Size](https://img.shields.io/docker/image-size/lissy93/dashy/latest?color=1eea76)
![Docker Cloud Build](https://img.shields.io/docker/cloud/automated/lissy93/dashy?color=f4a966&label=Docker%20Build)
](https://hub.docker.com/r/lissy93/dashy)
Dashy has a built container image hosted on [Docker Hub](https://hub.docker.com/r/lissy93/dashy). You will need [Docker](https://docs.docker.com/get-docker/) installed on your system.
```bash
docker run -d \
-p 8080:80 \
-v /root/my-local-conf.yml:/app/public/conf.yml \
--name my-dashboard \
--restart=always \
lissy93/dashy:latest
```
Explanation of the above options:
- `-d` Detached mode (not running in the foreground of your terminal)
- `-p` The port that should be exposed, and the port it should be mapped to in your host system `[host-port][container-port]`, leave the container port as is
- `-v` Specify volumes, to pass data from your host system to the container, in the format of `[host-path]:[container-path]`, you can use this to pass your config file, directory of assets (like icons), custom CSS or web assets (like favicon.ico, manifest.json etc)
- `--name` Give your container a human-readable name
- `--restart=always` Spin up the container when the daemon starts, or after it has been stopped
- `lissy93/dashy:latest` This last option is the image the container should be built from, you can also use a specific version or architecture type, by replacing `:latest` with one of the [tags](https://hub.docker.com/r/lissy93/dashy/tags)
For all available options, and to learn more, see the [Docker Run Docs](https://docs.docker.com/engine/reference/commandline/run/)
Dashy is also available through GHCR: `docker pull ghcr.io/lissy93/dashy:latest`
If you're deploying Dashy on a modern ARM-based board, such as a Raspberry Pi (2+), then you'll need to use one of Dashy's ARM images. Set the base image + tag to either `lissy93/dashy:arm64v8` or `lissy93/dashy:arm32v7`, depending on your system architecture. You can also use the `multi-arch` image, which should work on all system architectures.
The image defaults to `:latest`, but you can instead specify a specific version, e.g. `docker pull lissy93/dashy:release-1.5.0`
### Using Docker Compose
Using Docker Compose can be useful for saving your specific config in files, without having to type out a long run command each time. Save compose config as a YAML file, and then run `docker compose up` (optionally use the `-f` flag to specify file location, if it isn't located at `./docker-compose.yml`). Compose is also useful if you are using clusters, as the format is very similar to stack files, used with Docker Swarm.
The following is a complete example of a [`docker-compose.yml`](https://github.com/Lissy93/dashy/blob/master/docker-compose.yml) for Dashy. Run it as is, or uncomment the additional options you need.
```yaml
---
version: "3.8"
services:
dashy:
# To build from source, replace 'image: lissy93/dashy' with 'build: .'
# build: .
image: lissy93/dashy
container_name: Dashy
# Pass in your config file below, by specifying the path on your host machine
# volumes:
# - /root/my-config.yml:/app/public/conf.yml
ports:
- 4000:80
# Set any environmental variables
environment:
- NODE_ENV=production
# Specify your user ID and group ID. You can find this by running `id -u` and `id -g`
# - UID=1000
# - GID=1000
# Specify restart policy
restart: unless-stopped
# Configure healthchecks
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
```
You can use a different tag, by for example setting `image: lissy93/dashy:arm64v8`, or pull from GHCR instead by setting `image: ghcr.io/lissy93/dashy`.
If you are building from source, and would like to use one of the [other Dockerfiles](https://github.com/Lissy93/dashy/tree/master/docker), then under `services.dashy` first set `context: .`, then specify the the path to the dockerfile, e.g. `dockerfile: ./docker/Dockerfile-arm32v7`
### Build from Source
If you do not want to use Docker, you can run Dashy directly on your host system. For this, you will need both [git](https://git-scm.com/downloads) and the latest or LTS version of [Node.js](https://nodejs.org/) installed, and optionally [yarn](https://yarnpkg.com/)
1. Get Code: `git clone https://github.com/Lissy93/dashy.git` and `cd dashy`
2. Configuration: Fill in you're settings in `./public/conf.yml`
3. Install dependencies: `yarn`
4. Build: `yarn build`
5. Run: `yarn start`
### Deploy to cloud service
If you don't have a home server, then fear not - Dashy can be deployed to pretty much any cloud provider. The above Docker and NPM guides will work exactly the same on a VPS, but I've also setup some 1-Click deploy links for 10+ of the most common cloud providers, to make things easier. Note that if your instance is exposed to the internet, it will be your responsibility to adequately secure it.
Some hosting providers required a bit of extra configuration, which was why I've made separate branches for deploying to those services (named: [`deploy_cloudflare`](https://github.com/Lissy93/dashy/tree/deploy_cloudflare), [`deploy_digital-ocean`](https://github.com/Lissy93/dashy/tree/deploy_digital-ocean), [`deploy_platform-sh`](https://github.com/Lissy93/dashy/tree/deploy_platform-sh) and [`deploy_render`](https://github.com/Lissy93/dashy/tree/deploy_render)). If there's another cloud service which you'd like 1-click deployment to be supported for, feel free to raise an issue.
**Note** If you use a static hosting provider, then status checks, writing new config changes to disk from the UI, and triggering a rebuild through the UI will not be availible. This is because these features need endpoints provided by Dashy's local Node server. Everything else should work just the same though.
#### Netlify
[![Deploy to Netlify](https://i.ibb.co/GtKMysT/deploy-netlify-button.png)](https://app.netlify.com/start/deploy?repository=https://github.com/lissy93/dashy)
[Netlify](https://www.netlify.com/) offers Git-based serverless cloud hosting for web applications. Their services are free to use for personal use, and they support deployment from both public and private repos, as well as direct file upload. The free plan also allows you to use your own custom domain or sub-domain, and is easy to setup.
To deploy Dashy to Netlify, use the following link
```
https://app.netlify.com/start/deploy?repository=https://github.com/lissy93/dashy
```
#### Heroku
[![Deploy to Heroku](https://i.ibb.co/GdMFzBP/deploy-heroku-button.png)](https://heroku.com/deploy?template=https://github.com/Lissy93/dashy)
[Heroku](https://www.heroku.com/) is a fully managed cloud platform as a service. You define app settings in a Procfile and app.json, which specifying how the app should be build and how the server should be started. Heroku is free to use for unlimited, non-commercial, single dyno apps, and supports custom domains. Heroku's single-dyno service is not as quite performant as some other providers, and the app will have a short wake-up time when not visited for a while
To deploy Dashy to Heroku, use the following link
```
https://heroku.com/deploy?template=https://github.com/Lissy93/dashy
```
#### Cloudflare Workers
[![Deploy to Cloudflare Workers](https://i.ibb.co/jf9xVdm/deploy-cloudflare-button.png)](https://deploy.workers.cloudflare.com/?url=https://github.com/lissy93/dashy/tree/deploy_cloudflare)
[Cloudflare Workers](https://workers.cloudflare.com/) is a simple yet powerful service for running cloud functions and hosting web content. It requires a Cloudflare account, but is completely free for smaller projects, and very reasonably priced ($0.15/million requests per month) for large applications. You can use your own domain, and applications are protected with Cloudflare's state of the art DDoS protection. For more info, see the docs on [Worker Sites](https://developers.cloudflare.com/workers/platform/sites)
To deploy Dashy to Cloudflare, use the following link
```
https://deploy.workers.cloudflare.com/?url=https://github.com/lissy93/dashy/tree/deploy_cloudflare
```
#### Vercel
[![Deploy with Vercel](https://i.ibb.co/mJF3R7m/deploy-vercel-button.png)](https://vercel.com/new/project?template=https://github.com/lissy93/dashy)
[Vercel](https://vercel.com/) is a performance-focused platform for hosting static frontend apps. It comes bundled with some useful tools for monitoring and anaylzing application performance and other metrics. Vercel is free for personal use, allows for custom domains and has very reasonable limits.
To deploy Dashy to Vercel, use the following link
```
https://vercel.com/new/project?template=https://github.com/lissy93/dashy
```
#### DigitalOcean
[![Deploy to DO](https://i.ibb.co/PFt0PkB/deploy-digital-ocean-button.png)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/lissy93/dashy/tree/deploy_digital-ocean&refcode=3838338e7f79)
[DigitalOcan](https://www.digitalocean.com/) is a cloud service providing affordable developer-friendly virtual machines from $5/month. But they also have an app platform, where you can run web apps, static sites, APIs and background workers. CDN-backed static sites are free for personal use.
```
https://cloud.digitalocean.com/apps/new?repo=https://github.com/lissy93/dashy/tree/deploy_digital-ocean
```
#### Google Cloud Platform
[![Run on Google Cloud](https://i.ibb.co/LkvHttd/deploy-google-cloud-button.png)](https://deploy.cloud.run/?git_repo=https://github.com/lissy93/dashy.git)
[Cloud Run](https://cloud.google.com/run/) is a service offered by [Google Cloud](https://cloud.google.com/). It's a fully managed serverless platform, for developing and deploying highly scalable containerized applications. Similar to AWS and Azure, GCP offers a wide range of cloud services, which are billed on a payperuse basis, but Cloud Run has a [free tier](https://cloud.google.com/run/pricing) offering 180,000 vCPU-seconds, 360,000 GiB-seconds, and 2 million requests per month.
To deploy Dashy to GCP, use the following link
```
https://deploy.cloud.run/?git_repo=https://github.com/lissy93/dashy.git
```
#### Platform.sh
[![Deploy to Platform.sh](https://i.ibb.co/nPnJgJP/deploy-platform-sh-button.png)](https://console.platform.sh/projects/create-project/?template=https://github.com/lissy93/dashy&utm_campaign=deploy_on_platform?utm_medium=button&utm_source=affiliate_links&utm_content=https://github.com/lissy93/dashy)
[Platform.sh](https://platform.sh) is an end-to-end solution for developing and deploying applications. It is geared towards enterprise users with large teams, and focuses on allowing applications to scale up and down. Unlike the above providers, Platform.sh is not free, although you can deploy a test app to it without needing a payment method
To deploy Dashy to Platform.sh, use the following link
```
https://console.platform.sh/projects/create-project/?template=https://github.com/lissy93/dashy
```
#### Render
[![Deploy to Render](https://i.ibb.co/QXNCbxT/deploy-render-button.png)](https://render.com/deploy?repo=https://github.com/lissy93/dashy/tree/deploy_render)
[Render](https://render.com) is cloud provider that provides easy deployments for static sites, Docker apps, web services, databases and background workers. Render is great for developing applications, and very easy to use. Static sites are free, and services start at $7/month. Currently there are only 2 server locations - Oregon, USA and Frankfurt, Germany. For more info, see the [Render Docs](https://render.com/docs)
To deploy Dashy to Render, use the following link
```
https://render.com/deploy?repo=https://github.com/lissy93/dashy/tree/deploy_render
```
#### Scalingo
[![Deploy on Scalingo](https://i.ibb.co/nj0KxyH/deploy-scalingo-button.png)](https://my.scalingo.com/deploy?source=https://github.com/lissy93/dashy#master)
[Scalingo](https://scalingo.com/) is a scalable container-based cloud platform as a service. It's focus is on compliance and uptime, and is geared towards enterprise users. Scalingo is also not free, although they do have a 3-day free trial that does not require a payment method
To deploy Dashy to Scalingo, use the following link
```
https://my.scalingo.com/deploy?source=https://github.com/lissy93/dashy#master
```
#### Play-with-Docker
[![Try in PWD](https://i.ibb.co/SfbH7Zy/deploy-pwd-button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/Lissy93/dashy/master/docker-compose.yml)
[Play with Docker](https://labs.play-with-docker.com/) is a community project by Marcos Liljedhal and Jonathan Leibiusky and sponsored by Docker, intended to provide a hands-on learning environment. Their labs let you quickly spin up a Docker container or stack, and test out the image in a temporary, sandboxed environment. There's no need to sign up, and it's completely free.
To run Dashy in PWD, use the following URL:
```
https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/Lissy93/dashy/master/docker-compose.yml
```
#### Surge.sh
![Follow instructions below](https://i.ibb.co/XkcKzKz/deploy-surge-button.png)
[Surge.sh](http://surge.sh/) is quick and easy static web publishing platform for frontend-apps.
Surge supports [password-protected projects](https://surge.sh/help/adding-password-protection-to-a-project). You can also [add a custom domain](https://surge.sh/help/adding-a-custom-domain) and then [force HTTPS by default](https://surge.sh/help/using-https-by-default) and optionally [set a custom SSL certificate](https://surge.sh/help/securing-your-custom-domain-with-ssl)
To deploy Dashy to Surge.sh, first clone and cd into Dashy, install dependencies, and then use the following commands
```
yarn add -g surge
yarn build
surge ./dist
```
### Hosting with CDN
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.

View File

@ -1,309 +0,0 @@
# Developing
This article outlines how to get Dashy running in a development environment, and outlines the basics of the architecture.
If you're adding new features, you may want to check out the [Development Guides](/docs/development-guides) docs, for tutorials covering basic tasks.
- [Setting up the Development Environment](#setting-up-the-dev-environment)
- [Resources for Beginners](#resources-for-beginners)
- [Style Guide](#style-guide)
- [Frontend Components](#frontend-components)
- [Project Structure](#directory-structure)
- [Dependencies and Packages](#dependencies-and-packages)
## Setting up the Dev Environment
### Prerequisites
You will need either the latest or LTS version of **[Node.js](https://nodejs.org/)** to build and serve the application and **[Git](https://git-scm.com/downloads)** to easily fetch the code, and push any changes. If you plan on running or deploying the container, you'll also need **[Docker](https://docs.docker.com/get-docker/)**. To avoid any unexpected issues, ensure you've got at least **[NPM](https://www.npmjs.com/get-npm)** V 7.5 or **[Yarn](https://classic.yarnpkg.com/en/docs/install/#windows-stable)** 1.22 (you may find [NVM](https://github.com/nvm-sh/nvm) helpful for switching/ managing versions).
### Running the Project
1. Get Code: `git clone https://github.com/Lissy93/dashy.git`
2. Navigate into the directory: `cd dashy`
3. Install dependencies: `yarn`
4. Start dev server: `yarn dev`
Dashy should now be being served on http://localhost:8080/. Hot reload is enabled, so making changes to any of the files will trigger them to be rebuilt and the page refreshed.
### Project Commands
- `yarn dev` - Starts the development server with hot reloading
- `yarn build` - Builds the project for production, and outputs it into `./dist`
- `yarn start` - Starts a web server, and serves up the production site from `./dist`
- `yarn validate-config` - Parses and validates your `conf.yml` against Dashy's schema
- `yarn lint` - Lints code to ensure it follows a consistent, neat style
- `yarn test` - Runs tests, and outputs results
There is also:
- `yarn build-and-start` will run `yarn build` and `yarn start`
- `yarn build-watch` will output contents to `./dist` and recompile when anything in `./src` is modified, you can then use either `yarn start` or your own server, to have a production environment that watches for changes.
Using the Vue CLI:
- The app is build with Vue, and uses the [Vue-CLI Service](https://cli.vuejs.org/guide/cli-service.html) for basic commands.
- If you have [NPX](https://github.com/npm/npx) installed, then you can invoke the Vue CLI binary using `npx vue-cli-service [command]`
- Vue also has a GUI environment that can be used for basic project management, and may be useful for beginners, this can be started by running `vue ui`, and opening up `http://localhost:8000`
Note:
- If you are using NPM, replace `yarn` with `npm run`
- If you are using Docker, precede each command with `docker exec -it [container-id]`. Container ID can be found by running `docker ps`
### Environmental Variables
All environmental variables are optional. Currently there are not many environmental variables used, as most of the user preferences are stored under `appConfig` in the `conf.yml` file.
You can set variables within your local development environment using a `.env` file.
Any environmental variables used by the frontend are preceded with `VUE_APP_`. Vue will merge the contents of your `.env` file into the app in a similar way to the ['dotenv'](https://github.com/motdotla/dotenv) package, where any variables that you set on your system will always take preference over the contents of any `.env` file.
- `PORT` - The port in which the application will run (defaults to `4000` for the Node.js server, and `80` within the Docker container)
- `NODE_ENV` - Which environment to use, either `production`, `development` or `test`
- `VUE_APP_DOMAIN` - The URL where Dashy is going to be accessible from. This should include the protocol, hostname and (if not 80 or 443), then the port too, e.g. `https://localhost:3000`, `http://192.168.1.2:4002` or `https://dashy.mydomain.com`
If you do add new variables, ensure that there is always a fallback (define it in [`defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js)), so as to not cause breaking changes. Don't commit your `.env` file to git, but instead take a few moments to document what you've added under the appropriate section. Try and follow the concepts outlined in the [12 factor app](https://12factor.net/config).
### Environment Modes
You can set the environment using the `NODE_ENV` variable.
The correct environment will be selected based on the script you run by default
The following environments are supported.
- `production`
- `development`
- `test`
For more info, see [Vue CLI Environment Modes](https://cli.vuejs.org/guide/mode-and-env.html#modes).
---
## Git Strategy
### Git Flow
Like most Git repos, we are following the [Github Flow](https://guides.github.com/introduction/flow) standard.
1. Create a branch (or fork if you don'd have write acces)
2. Code some awesome stuff, then add and commit your changes
3. Create a Pull Request, complete the checklist and ensure the build succeeds
4. Follow up with any reviews on your code
5. Merge 🎉
### Git Branch Naming
The format of your branch name should be something similar to: `[TYPE]/[TICKET]_[TITLE]`
For example, `FEATURE/420_Awesome-feature` or `FIX/690_login-server-error`
### Commit Emojis
Using a single emoji at the start of each commit message, to indicate the type task, makes the commit ledger easier to understand, plus it looks cool.
- 🎨 `:art:` - Improve structure / format of the code.
- ⚡️ `:zap:` - Improve performance.
- 🔥 `:fire:` - Remove code or files.
- 🐛 `:bug:` - Fix a bug.
- 🚑️ `:ambulance:` - Critical hotfix
- ✨ `:sparkles:` - Introduce new features.
- 📝 `:memo:` - Add or update documentation.
- 🚀 `:rocket:` - Deploy stuff.
- 💄 `:lipstick:` - Add or update the UI and style files.
- 🎉 `:tada:` - Begin a project.
- ✅ `:white_check_mark:` - Add, update, or pass tests.
- 🔒️ `:lock:` - Fix security issues.
- 🔖 `:bookmark:` - Make a Release or Version tag.
- 🚨 `:rotating_light:` - Fix compiler / linter warnings.
- 🚧 `:construction:` - Work in progress.
- ⬆️ `:arrow_up:` - Upgrade dependencies.
- 👷 `:construction_worker:` - Add or update CI build system.
- ♻️ `:recycle:` - Refactor code.
- 🩹 `:adhesive_bandage:` - Simple fix for a non-critical issue.
- 🔧 `:wrench:` - Add or update configuration files.
- 🍱 `:bento:` - Add or update assets.
- 🗃️ `:card_file_box:` - Perform database schema related changes.
- ✏️ `:pencil2:` - Fix typos.
- 🌐 `:globe_with_meridians:` - Internationalization and translations.
For a full list of options, see [gitmoji.dev](https://gitmoji.dev/)
### PR Guidelines
Once you've made your changes, and pushed them to your fork or branch, you're ready to open a pull request!
For a pull request to be merged, it must:
- Must be backwards compatible
- The build, lint and tests (run by GH actions) must pass
- There must not be any merge conflicts
When you submit your PR, include the required info, by filling out the PR template. Including:
- A brief description of your changes
- The issue, ticket or discussion number (if applicable)
- For UI relate updates include a screenshot
- If any dependencies were added, explain why it was needed, state the cost associated, and confirm it does not introduce any security issues
- Finally, check the checkboxes, to confirm that the standards are met, and hit submit!
---
## 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:
- [Introduction to Vue.js](https://v3.vuejs.org/guide/introduction.html)
- [Vue.js Walkthrough](https://www.taniarascia.com/getting-started-with-vue/)
- [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/)
- [Quick start TypeScript guide](https://www.freecodecamp.org/news/learn-typescript-in-5-minutes-13eda868daeb/)
- [Complete TypeScript tutorial series](https://www.typescripttutorial.net/)
- [Using TypeScript with Vue.js](https://blog.logrocket.com/vue-typescript-tutorial-examples/)
- [Git cheat sheet](http://git-cheatsheet.com/)
- [Basics of using NPM](https://www.freecodecamp.org/news/what-is-npm-a-node-package-manager-tutorial-for-beginners/)
As well as Node, Git and Docker- you'll also need an IDE (e.g. [VS Code](https://code.visualstudio.com/) or [Vim](https://www.vim.org/)) and a terminal (Windows users may find [WSL](https://docs.microsoft.com/en-us/windows/wsl/) more convenient).
---
## Style Guide
Linting is done using [ESLint](https://eslint.org/), and using the [Vue.js Styleguide](https://github.com/vuejs/eslint-config-standard), which is very similar to the [AirBnB Stylguide](https://github.com/airbnb/javascript). You can run `yarn lint` to report and fix issues. While the dev server is running, issues will be reported to the console automatically, and any lint errors will trigger the build to fail. Note that all lint checks must pass before any PR can be merged. Linting is also run as a git pre-commit hook
The most significant things to note are:
- Indentation should be done with two spaces
- Strings should use single quotes
- All statements must end in a semi-colon
- The final element in all objects must be preceded with a comma
- Maximum line length is 100
- There must be exactly one blank line between sections, before function names, and at the end of the file
- With conditionals, put else on the same line as your if blocks closing brace
- All multiline blocks must use braces
- Avoid console statements in the frontend
Styleguides:
- Vue: [Vue styleguide](https://vuejs.org/v2/style-guide/)
- JavaScript: [github.com/airbnb/javascript](https://github.com/airbnb/javascript)
---
## Application Structure
### Directory Structure
#### Files in the Root: `./`
```
├── package.json # Project meta-data, dependencies and paths to scripts
├── src/ # Project front-end source code
├── server.js # A Node.js server to serve up the /dist directory
├── vue.config.js # Vue.js configuration
├── Dockerfile # The blueprint for building the Docker container
├── docker-compose.yml # A Docker run command
├── .env # Location for any environmental variables
├── yarn.lock # Auto-generated list of current packages and version numbers
├── docs/ # Markdown documentation
├── README.md # Readme, basic info for getting started
├── LICENSE.md # License for use
```
#### Frontend Source: `./src/`
```
./src
├── App.vue # Vue.js starting file
├── assets # Static non-compiled assets
│ ├── fonts # .ttf font files
│ ├── locales # All app text, each language in a separate JSON file
│ ╰── interface-icons # SVG icons used in the app
├── components # All front-end Vue web components
│ ├── Configuration # Components relating to the user config pop-up
│ │ ├── AppInfoModal.vue # A modal showing core app info, like version, language, etc
│ │ ├── CloudBackupRestore.vue # Form where the user manages cloud sync options
│ │ ├── ConfigContainer.vue # Main container, wrapping all other config components
│ │ ├── CustomCss.vue # Form where the user can input custom CSS
│ │ ├── EditSiteMeta.vue # Form where the user can edit site meta data
│ │ ├── JsonEditor.vue # JSON editor, where the user can modify the main config file
│ │ ╰── RebuildApp.vue # A component allowing user to trigger a rebuild through the UI
│ ├── FormElements # Basic form elements used throughout the app
│ │ ├── Button.vue # Standard button component
│ │ ╰── Input.vue # Standard text field input component
│ ├── LinkItems # Components for Sections and Link Items
│ │ ├── Collapsable.vue # The collapsible functionality of sections
│ │ ├── ContextMenu.vue # The right-click menu, for showing Item opening methods and info
│ │ ├── IframeModal.vue # Pop-up iframe modal, for viewing websites within the app
│ │ ├── Item.vue # Main link item, which is displayed within an item group
│ │ ├── ItemGroup.vue # Item group is a section containing icons
│ │ ├── ItemIcon.vue # The icon used by both items and sections
│ │ ├── ItemOpenMethodIcon.vue # A small icon, visible on hover, indicating opening method
│ │ ╰── StatusIndicator.vue # Traffic light dot, showing if app is online or down
│ ├── PageStrcture # Components relating the main structure of the page
│ │ ├── Footer.vue # Footer, visible at the bottom of all pages
│ │ ├── Header.vue # Header, visible at the top of pages, and includes title and nav
│ │ ├── LoadingScreen.vue # Splash screen shown on first load
│ │ ├── Nav.vue # Navigation bar, includes a list of links
│ │ ╰── PageTitle.vue # Page title and sub-title, visible within the Header
│ ╰── Settings # Components relating to the quick-settings, in the top-right
│ ├── AuthButtons.vue # Logout button and other app info
│ ├── ConfigLauncher.vue # Icon that when clicked will launch the Configuration component
│ ├── CustomThemeMaker.vue # Color pickers for letting user build their own theme
│ ├── ItemSizeSelector.vue # Set of buttons used to set and save item size
│ ├── KeyboardShortcutInfo.vue# Small pop-up displaying the available keyboard shortcuts
│ ├── LanguageSwitcher.vue # Dropdown in a modal for changing app language
│ ├── LayoutSelector.vue # Set of buttons, letting the user select their desired layout
│ ├── SearchBar.vue # The input field in the header, used for searching the app
│ ├── SettingsContainer.vue # Container that wraps all the quick-settings components
│ ╰── ThemeSelector.vue # Drop-down menu enabling the user to select and change themes
├── main.js # Main front-end entry point
├── registerServiceWorker.js # Registers and manages service workers, for PWA apps
├── router.js # Defines all available application routes
├── styles # Directory of all globally used common SCSS styles
├── utils # Directory of re-used helper functions
│ ├── ArrowKeyNavigation.js # Functionality for arrow-key navigation
│ ├── Auth.js # Handles all authentication related actions
│ ├── ClickOutside.js # A directive for detecting click, used to hide dropdown, modal or context menu
│ ├── ConfigAccumulator.js # Central place for managing and combining config
│ ├── ConfigHelpers.js # Helper functions for managing configuration
│ ├── CloudBackup.js # Functionality for encrypting, processing and network calls
│ ├── ConfigSchema.json # The schema, used to validate the users conf.yml file
│ ├── ConfigValidator.js # A helper script that validates the config file against schema
│ ├── defaults.js # Global constants and their default values
│ ├── ErrorHandler.js # Helper function called when an error is returned
│ ├── JsonToYaml.js # Function that parses and converts raw JSON into valid YAML
│ ├── languages.js # Handles fetching, switching and validating languages
│ ╰── ThemeHelper.js # Function that handles the fetching and setting of user themes
╰── views # Directory of available pages, corresponding to available routes
├── Home.vue # The home page container
├── About.vue # About page
├── Login.vue # TAuthentication page
├── Minimal.vue # The minimal view
╰── Workspace.vue # The workspace view with apps in sidebar
```
### Frontend Components
All frontend code is located in the `./src` directory, which is split into 5 sub-folders:
- **Components** - All frontend web components are located here. Each component should have a distinct, well defined and simple task, and ideally should not be too long. The components directory is organised into a series of sub-directories, representing a specific area of the application
- **PageStrcture** - Components relating to overall page structure (nav, footer, etc)
- FormElements - Reusable form elements (button, input field, etc)
- LinkItems - Components relating to Dashy's sections and items (item group, item, item icon, etc)
- Configuration - Components relating to Dashy's configuration forms (cloud backup, JSON editor, etc)
- **Views** - Each view directly corresponds to a route (defined in the router), and in effectively a page. They should have minimal logic, and just contain a few components
- **Utils** - These are helper functions, or logic that is used within the app does not include an UI elements
- **Styles** - Any SCSS that is used globally throughout that app, and is not specific to a single component goes here. This includes variables, color themes, typography settings, CSS reset and media queries
- **Assets** - Static assets that need to be bundled into the application, but do not require any manipulation go here. This includes interface icons and fonts
The structure of the components directory is similar to that of the frontend application layout
<p align="center"><img src="https://i.ibb.co/wJCt0Lq/dashy-page-structure.png" width="600"/></p>
---
## Development Tools
### Performance - Lighthouse
The easiest method of checking performance is to use Chromium's build in auditing tool, Lighthouse. To run the test, open Developer Tools (usually F12) --> Lighthouse and click on the 'Generate Report' button at the bottom.
### Dependencies - BundlePhobia
[BundlePhobia](https://bundlephobia.com/) is a really useful app that lets you analyze the cost of adding any particular dependency to an application
---
## Notes
### Known Warnings
When running the build command, several warnings appear. These are not errors, and do not affect the security or performance of the application. They will be addressed in a future update
`WARN A new version of sass-loader is available. Please upgrade for best experience.` - Currently we're using an older version of SASS loader, since the more recent releases do not seem to be compatible with the Vue CLI's webpack configuration.
`WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).` - For the PWA to support Windows 10, a splash screen asset is required, and is quite large. This throws a warning, however PWA assets are not loaded until needed, so shouldn't have any impact on application performance. A similar warning is thrown for the Raleway font, and that is looking to be addressed.
`glob-parent Security Alert` - This will be fixed soon. The version of glob-parent that is used by the latest version of Vue-CLI has a security issue associated with it. I am waiting on Vue to update their dependencies.

View File

@ -1,178 +0,0 @@
# Development Guides
A series of short tutorials, to guide you through the most common development tasks.
Sections:
- [Creating a new theme](#creating-a-new-theme)
- [Writing Translations](#writing-translations)
- [Adding a new option in the config file](#adding-a-new-option-in-the-config-file)
- [Updating Dependencies](#updating-dependencies)
## Creating a new theme
Adding a new theme is really easy. There's two things you need to do: Pass the theme name to Dashy, so that it can be added to the theme selector dropdown menu, and then write some styles!
##### 1. Add Theme Name
Choose a snappy name for you're theme, and add it to the `builtInThemes` array inside [`defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js#L27).
##### 2. Write some Styles!
Put your theme's styles inside [`color-themes.scss`](https://github.com/Lissy93/dashy/blob/master/src/styles/color-themes.scss).
Create a new block, and make sure that `data-theme` matches the theme name you chose above. For example:
```css
html[data-theme='tiger'] {
--primary: #f58233;
--background: #0b1021;
}
```
Then you can go ahead and write you're own custom CSS. Although all CSS is supported here, the best way to define you're theme is by setting the CSS variables. You can find a [list of all CSS variables, here](https://github.com/Lissy93/dashy/blob/master/docs/theming#css-variables).
For a full guide on styling, see [Theming Docs](./theming).
Note that if you're theme is just for yourself, and you're not submitting a PR, then you can instead just pass it under `appConfig.cssThemes` inside your config file. And then put your theme in your own stylesheet, and pass it into the Docker container - [see how](https://github.com/Lissy93/dashy/blob/master/docs/theming#adding-your-own-theme).
## Writing Translations
For full docs about Dashy's multi-language support, see [Multi-Language Support](./multi-language-support)
Dashy is using [vue-i18n](https://vue-i18n.intlify.dev/guide/) to manage multi-language support.
Adding a new language is pretty straightforward, with just three steps:
##### 1. Create a new Language File
Create a new JSON file in `./src/assets/locales` name is a 2-digit [ISO-639 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, E.g. for German `de.json`, French `fr.json` or Spanish `es.json` - You can find a list of all ISO codes at [iso.org](https://www.iso.org/obp/ui).
##### 2. Translate!
Using [`en.json`](https://github.com/Lissy93/dashy/tree/master/src/assets/locales/en.json) as an example, translate the JSON values to your language, while leaving the keys as they are. It's fine to leave out certain items, as if they're missing they will fall-back to English. If you see any attribute which include curly braces (`{xxx}`), then leave the inner value of these braces as is, as this is for variables.
```json
{
"theme-maker": {
"export-button": "Benutzerdefinierte Variablen exportieren",
"reset-button": "Stile zurücksetzen für",
"show-all-button": "Alle Variablen anzeigen",
"save-button": "Speichern",
"cancel-button": "Abbrechen",
"saved-toast": "{theme} Erfolgreich aktualisiert",
"reset-toast": "Benutzerdefinierte Farben für {theme} entfernt"
},
}
```
##### 3. Add your file to the app
In [`./src/utils/languages.js`](https://github.com/Lissy93/dashy/tree/master/src/utils/languages.js), you need to do 2 small things:
First import your new translation file, do this at the top of the page.
E.g. `import de from '@/assets/locales/de.json';`
Second, add it to the array of languages, e.g:
```javascript
export const languages = [
{
name: 'English',
code: 'en',
locale: en,
flag: '🇬🇧',
},
{
name: 'German', // The name of your language
code: 'de', // The ISO code of your language
locale: de, // The name of the file you imported (no quotes)
flag: '🇩🇪', // An optional flag emoji
},
];
```
You can also add your new language to the readme, under the [Language Switching](https://github.com/Lissy93/dashy#language-switching-) section, and optionally include your name/ username if you'd like to be credited for your work. Done!
If you are not comfortable with making pull requests, or do not want to modify the code, then feel free to instead send the translated file to me, and I can add it into the application. I will be sure to credit you appropriately.
# Adding a new option in the config file
This section is for, if you're adding a new component or setting, that requires an additional item to be added to the users config file.
All of the users config is specified in `./public/conf.yml` - see [Configuring Docs](./configuring) for info.
Before adding a new option in the config file, first ensure that there is nothing similar available, that is is definitely necessary, it will not conflict with any other options and most importantly that it will not cause any breaking changes. Ensure that you choose an appropriate and relevant section to place it under.
Next decide the most appropriate place for your attribute:
- Application settings should be located under `appConfig`
- Page info (such as text and metadata) should be under `pageInfo`
- Data relating to specific sections should be under `section[n].displayData`
- And for setting applied to specific items, it should be under `item[n]`
In order for the user to be able to add your new attribute using the Config Editor, and for the build validation to pass, your attribute must be included within the [ConfigSchema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.js). You can read about how to do this on the [ajv docs](https://ajv.js.org/json-schema.html). Give your property a type and a description, as well as any other optional fields that you feel are relevant. For example:
```json
"fontAwesomeKey": {
"type": "string",
"pattern": "^[a-z0-9]{10}$",
"description": "API key for font-awesome",
"example": "0821c65656"
}
```
or
```json
"iconSize": {
"enum": [ "small", "medium", "large" ],
"default": "medium",
"description": "The size of each link item / icon"
}
```
Next, if you're property should have a default value, then add it to [`defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js). This ensures that nothing will break if the user does not use your property, and having all defaults together keeps things organised and easy to manage.
If your property needs additional logic for fetching, setting or processing, then you can add a helper function within [`ConfigHelpers.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigHelpers.js).
Finally, add your new property to the [`configuring.md`](./configuring) API docs. Put it under the relevant section, and be sure to include field name, data type, a description and mention that it is optional. If your new feature needs more explaining, then you can also document it under the relevant section elsewhere in the documentation.
Checklist:
- [ ] Ensure the new attribute is actually necessary, and nothing similar already exists
- [ ] Update the [Schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.js) with the parameters for your new option
- [ ] Set a default value (if required) within [`defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js)
- [ ] Document the new value in [`configuring.md`](./configuring)
- [ ] Test that the reading of the new attribute is properly handled, and will not cause any errors when it is missing or populated with an unexpected value
---
## Updating Dependencies
Running `yarn upgrade` will updated all dependencies based on the ranges specified in the `package.json`. The `yarn.lock` file will be updated, as will the contents of `./node_modules`, for more info, see the [yarn upgrade documentation](https://classic.yarnpkg.com/en/docs/cli/upgrade/). It is important to thoroughly test after any big dependency updates.
---
## Hiding Page Furniture on Certain Routes
For some pages (such as the login page, the minimal start page, etc) the basic page furniture, (like header, footer, nav, etc) is not needed. This section explains how you can hide furniture on a new view (step 1), or add a component that should be hidden on certain views (step 2).
##### 1. Add the route name to the should hide array
In [`./src/utils/defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js), there's an array called `hideFurnitureOn`. Append the name of the route (the same as it appears in [`router.js`](https://github.com/Lissy93/dashy/blob/master/src/router.js)) here.
##### 2. Add the conditional to the structural component to hide
First, import the helper function:
```javascript
import { shouldBeVisible } from '@/utils/MiscHelpers';
```
Then you can create a computed value, that calls this function, passing in the route name:
```javascript
export default {
...
computed: {
...
isVisible() {
return shouldBeVisible(this.$route.name);
},
},
};
```
Finally, in the markup of your component, just add a `v-if` statement, referencing your computed value
```vue
<header v-if="isVisible">
...
</header>
```
---

View File

@ -1,100 +0,0 @@
# Icons
Both sections and items can have an icon, which is specified using the `icon` attribute. Using icons improves the aesthetics of your UI and makes the app more intuitive to use. There are several options when it comes to setting icons, and this article outlines each of them
- [Font Awesome Icons](#font-awesome)
- [Auto-Fetched Favicons](#favicons)
- [Generative Icons](#generative-icons)
- [Emoji Icons](#emoji-icons)
- [Icons by URL](#icons-by-url)
- [Local Icons](#local-icons)
- [No Icon](#no-icon)
<p align="center">
<img width="500" src="https://i.ibb.co/GTVmZnc/dashy-example-icons.png" />
</p>
Note that, if you are using icons from an external source (like font-awesome or material-design-icons), then the relevant font file will be loaded in automatically if and when needed, but combining icons from multiple services may have a negative impact on performance.
### Font Awesome
You can use any [Font Awesome Icon](https://fontawesome.com/icons) simply by specifying it's identifier. This is in the format of `[category] [name]` and can be found on the page for any given icon on the Font Awesome site. For example: `fas fa-rocket`, `fab fa-monero` or `fas fa-unicorn`.
Font-Awesome has a wide variety of free icons, but you can also use their pro icons if you have a membership. To do so, you need to specify your license key under: `appConfig.fontAwesomeKey`. This is usually a 10-digit string, for example `13014ae648`.
<p align="center">
<img width="580" src="https://i.ibb.co/pdrw8J4/fontawesome-icons2.png" />
</p>
### Favicons
Dashy can auto-fetch the favicon for a given service using it's URL. Just set `icon: favicon` to use this feature. If the services URL is a local IP, then Dashy will attempt to find the favicon from `http://[ip]/favicon.ico`. This has two issues, favicons are not always hosted at the same location for every service, and often the default favicon is a low resolution. Therefore to fix this, for remote services an API is used to return a high-quality icon for any online service.
<p align="center">
<img width="580" src="https://i.ibb.co/k6wyhnB/favicon-icons.png" />
</p>
The default favicon API is [Favicon Kit](https://faviconkit.com/), a free and reliable service for returning images from any given URL. However several other API's are supported. To change the API used, under `appConfig`, set `faviconApi` to one of the following values:
- `faviconkit` - [faviconkit.com](https://faviconkit.com/) (Recommend)
- `google` - Official Google favicon API service, good support for all sites, but poor quality
- `clearbit` - [Clearbit](https://clearbit.com/logo) returns high-quality logos from mainstream websites
- `webmasterapi` - [WebMasterAPI](https://www.webmasterapi.com/get-favicons)
- `allesedv` - [allesedv.com](https://favicon.allesedv.com/) is a highly efficient IPv6-enabled service
You can also force Dashy to always get favicons from the root of the domain, and not use an external service, by setting `appConfig.faviconApi` to `local`.
### Generative Icons
Uses a unique and programmatically generated icon for a given service. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with [ipsicon.io](https://ipsicon.io/). To use this option, just set an item's to: `icon: generative`.
<p align="center">
<img width="400" src="https://i.ibb.co/qrNNNcm/generative-icons.png" />
</p>
### Emoji Icons
You can use almost any emoji as an icon for items or sections. You can specify the emoji either by pasting it directly, using it's unicode ( e.g. `'U+1F680'`) or shortcode (e.g. `':rocket:'`). You can find these codes for any emoji using [Emojipedia](https://emojipedia.org/) (near the bottom of emoji each page), or for a quick reference to emoji shortcodes, check out [emojis.ninja](https://emojis.ninja/) by @nomanoff.
<p align="center">
<img width="580" src="https://i.ibb.co/YLwgTf9/emoji-icons-1.png" />
</p>
The following examples will all render the same rocket (🚀) emoji:
```yaml
items:
- title: Shortcode
icon: ':rocket:'
- title: Unicode
icon: 'U+1F680'
- title: Emoji
icon: 🚀
```
### Icons by URL
You can also set an icon by passing in a valid URL pointing to the icons location. For example `icon: https://i.ibb.co/710B3Yc/space-invader-x256.png`, this can be in .png, .jpg or .svg format, and hosted anywhere- so long as it's accessible from where you are hosting Dashy. The icon will be automatically scaled to fit, however loading in a lot of large icons may have a negative impact on performance, especially if you visit Dashy from new devices often.
### Local Icons
You may also want to store your icons locally, bundled within Dashy so that there is no reliance on outside services. This can be done by putting the icons within Dashy's `./public/item-icons/` directory. If you are using Docker, then the easiest option is to map a volume from your host system, for example: `-v /local/image/directory:/app/public/item-icons/`. To reference an icon stored locally, just specify it's name and extension. For example, if my icon was stored in `/app/public/item-icons/maltrail.png`, then I would just set `icon: maltrail.png`.
You can also use sub-folders within the `item-icons` directory to keep things organised. You would then specify an icon with it's folder name slash image name. For example: `networking/monit.png`
### Material Design Icons
Dashy also supports 5000+ [material-design-icons](https://github.com/Templarian/MaterialDesign). To use these, first find the name/ slug for your icon [here](https://dev.materialdesignicons.com/icons), and then prefix is with `mdi-`.
For example:
```yaml
sections:
- name: Material Design Icons Example
items:
- title: Alien Icon
icon: mdi-alien
- title: Fire Icon
icon: mdi-fire
- title: Dino Icon
icon: mdi-google-downasaur
```
### Simple Icons
To use glyphs from [SimpleIcons.org](https://simpleicons.org/), first find the icon slug, and then prefix it with `si-`. The image will be loaded directly from the Simple Icons
### No Icon
If you don't wish for a given item or section to have an icon, just leave out the `icon` attribute.

View File

@ -1,24 +0,0 @@
```
MIT License
Copyright (c) 2021 Alicia Sykes <https://aliciasykes.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

View File

@ -1,192 +0,0 @@
# 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.
- `./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. You then reference these assets relative this the direcroties path, for example: to use `./public/item-icons/networking/netdata.png` as an icon for one of your links, you would set `icon: networking/netdata.png`
- Also within `./public` you'll find standard website assets, including `favicon.ico`, `manifest.json`, `robots.txt`, etc. There's no need to modify these, but you can do so if you wish.
## Basic Commands
Now that you've got Dashy running, there are a few commands that you need to know.
The following commands are defined in the [`package.json`](https://github.com/Lissy93/dashy/blob/master/package.json#L5) file, and are run with `yarn`. If you prefer, you can use NPM, just replace instances of `yarn` with `npm run`. If you are using Docker, then you will need to precede 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`.
- **`yarn build`** - In the interest of speed, the application is pre-compiled, this means that the config file is read during build-time, and therefore the app needs to rebuilt for any new changes to take effect. Luckily this is very straight forward. Just run `yarn build` or `docker exec -it [container-id] yarn build`
- **`yarn validate-config`** - If you have quite a long configuration file, you may wish to check that it's all good to go, before deploying the app. This can be done with `yarn validate-config` or `docker exec -it [container-id] yarn validate-config`. Your config file needs to be in `/public/conf.yml` (or within your Docker container at `/app/public/conf.yml`). This will first check that your YAML is valid, and then validates it against Dashy's [schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.js).
- **`yarn health-check`** - Checks that the application is up and running on it's specified port, and outputs current status and response times. Useful for integrating into your monitoring service, if you need to maintain high system availability
- **`yarn build-watch`** - If you find yourself making frequent changes to your configuration, and do not want to have to keep manually rebuilding, then this option is for you. It will watch for changes to any files within the projects root, and then trigger a rebuild. Note that if you are developing new features, then `yarn dev` would be more appropriate, as it's significantly faster at recompiling (under 1 second), and has hot reloading, linting and testing integrated
- **`yarn build-and-start`** - Builds the app, runs checks and starts the production server. Commands are run in parallel, and so is faster than running them in independently
- **`yarn pm2-start`** - Starts the Node server using [PM2](https://pm2.keymetrics.io/), a process manager for Node.js applications, that helps them stay alive. PM2 has some built-in basic monitoring features, and an optional [management solution](https://pm2.io/). If you are running the app on bare metal, it is recommended to use this start command
## 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).
## Logs and Performance
#### Container Logs
You can view logs for a given Docker container with `docker logs [container-id]`, add the `--follow` flag to stream the logs. For more info, see the [Logging Documentation](https://docs.docker.com/config/containers/logging/). There's also [Dozzle](https://dozzle.dev/), a useful tool, that provides a web interface where you can stream and query logs from all your running containers from a single web app.
#### Container Performance
You can check the resource usage for your running Docker containers with `docker stats` or `docker stats [container-id]`. For more info, see the [Stats Documentation](https://docs.docker.com/engine/reference/commandline/stats/). There's also [cAdvisor](https://github.com/google/cadvisor), a useful web app for viewing and analyzing resource usage and performance of all your running containers.
#### Management Apps
You can also view logs, resource usage and other info as well as manage your entire Docker workflow in third-party Docker management apps. For example [Portainer](https://github.com/portainer/portainer) an all-in-one open source management web UI for Docker and Kubernetes, or [LazyDocker](https://github.com/jesseduffield/lazydocker) a terminal UI for Docker container management and monitoring.
#### 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).
## 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/).
For Podman, you can use `systemd` to create a service that launches your container, [the docs](https://podman.io/blogs/2018/09/13/systemd.html) explains things further. A similar approach can be used with Docker, if you need to start containers after a reboot, but before any user interaction.
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) 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#alternative-authentication-methods) for options regarding securing Dashy.
**[⬆️ Back to Top](#)**
---
## Updating
Dashy is under active development, so to take advantage of the latest features, you may need to update your instance every now and again.
### Updating Docker Container
1. Pull latest image: `docker pull lissy93/dashy:latest`
2. Kill off existing container
- Find container ID: `docker ps`
- Stop container: `docker stop [container_id]`
- Remove container: `docker rm [container_id]`
3. Spin up new container: `docker run [params] lissy93/dashy`
### Automatic Docker Updates
You can automate the above process using [Watchtower](https://github.com/containrrr/watchtower).
Watchtower will watch for new versions of a given image on Docker Hub, pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
To get started, spin up the watchtower container:
```
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
```
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`
**[⬆️ Back to Top](#)**
---
## Web Server Configuration
_The following section only applies if you are not using Docker, and would like to use your own web server_
Dashy ships with a pre-configured Node.js server, in [`server.js`](https://github.com/Lissy93/dashy/blob/master/server.js) which serves up the contents of the `./dist` directory on a given port. You can start the server by running `node server`. Note that the app must have been build (run `yarn build`), and you need [Node.js](https://nodejs.org) installed.
If you wish to run Dashy from a sub page (e.g. `example.com/dashy`), then just set the `BASE_URL` environmental variable to that page name (in this example, `/dashy`), before building the app, and the path to all assets will then resolve to the new path, instead of `./`.
However, since Dashy is just a static web application, it can be served with whatever server you like. The following section outlines how you can configure a web server.
Note, that if you choose not to use `server.js` to serve up the app, you will loose access to the following features:
- Loading page, while the app is building
- Writing config file to disk from the UI
- Website status indicators, and ping checks
### NGINX
Create a new file in `/etc/nginx/sites-enabled/dashy`
```
server {
listen 80;
listen [::]:80;
root /var/www/dashy/html;
index index.html;
server_name your-domain.com www.your-domain.com;
location / {
try_files $uri $uri/ =404;
}
}
```
Then upload the build contents of Dashy's dist directory to that location.
For example: `scp -r ./dist/* [username]@[server_ip]:/var/www/dashy/html`
### Apache
Copy Dashy's dist folder to your apache server, `sudo cp -r ./dashy/dist /var/www/html/dashy`.
In your Apache config, `/etc/apche2/apache2.conf` add:
```
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
```
Add a `.htaccess` file within `/var/www/html/dashy/.htaccess`, and add:
```
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
```
Then restart Apache, with `sudo systemctl restart apache2`
### cPanel
1. Login to your WHM
2. Open 'Feature Manager' on the left sidebar
3. Under 'Manage feature list', click 'Edit'
4. Find 'Application manager' in the list, enable it and hit 'Save'
5. Log into your users cPanel account, and under 'Software' find 'Application Manager'
6. Click 'Register Application', fill in the form using the path that Dashy is located, and choose a domain, and hit 'Save'
7. The application should now show up in the list, click 'Ensure dependencies', and move the toggle switch to 'Enabled'
8. If you need to change the port, click 'Add environmental variable', give it the name 'PORT', choose a port number and press 'Save'.
9. Dashy should now be running at your selected path an on a given port
**[⬆️ Back to Top](#)**
---
## Authentication
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)**.
**[⬆️ Back to Top](#)**

View File

@ -1,164 +0,0 @@
# Internationalization
Internationalization is the process of making an application available in other languages. This is important, as not everyone is a native English speaker.
## Available Languages
An up-to-date list of all currently supported languages can be found in [`./src/utils/languages.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/languages.js). Languages are specified by their 2-digit [ISO-639 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`, `fr`, `de`, `es`, etc)
---
## How to change Language
By default, Dashy will attempt to use the language of your browser or system. If a translation for your language does not yet exist, it will fallback to English.
You can also manually select your language. This can be done, either through the UI (Config --> Language), or by setting it in your config file:
```yaml
appConfig:
lang: de
```
---
## Adding a new Language
Dashy is using [vue-i18n](https://vue-i18n.intlify.dev/guide/) to manage multi-language support.
Adding a new language is pretty straightforward, with just three steps:
##### 1. Create a new Language File
Create a new JSON file in `./src/assets/locales` name is a 2-digit [ISO-639 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, E.g. for German `de.json`, French `fr.json` or Spanish `es.json` - You can find a list of all ISO codes at [iso.org](https://www.iso.org/obp/ui).
If your language is a specific dialect or regional language, then use the Posfix [CLDR](http://cldr.unicode.org/) format, where, e.g. `en-GB.json` (British), `es-MX.json` (Spanish, in Mexico) or `zh-CN.json` (Chinese, simplified) - A list of which can be found [here](https://github.com/unicode-org/cldr-json/blob/master/cldr-json/cldr-core/availableLocales.json)
##### 2. Translate!
Using [`en.json`](https://github.com/Lissy93/dashy/tree/master/src/assets/locales/en.json) as an example, translate the JSON values to your language, while leaving the keys as they are. It's fine to leave out certain items, as if they're missing they will fall-back to English. If you see any attribute which include curly braces (`{xxx}`), then leave the inner value of these braces as is, as this is for variables.
```json
{
"theme-maker": {
"export-button": "Benutzerdefinierte Variablen exportieren",
"reset-button": "Stile zurücksetzen für",
"show-all-button": "Alle Variablen anzeigen",
"save-button": "Speichern",
"cancel-button": "Abbrechen",
"saved-toast": "{theme} Erfolgreich aktualisiert",
"reset-toast": "Benutzerdefinierte Farben für {theme} entfernt"
},
}
```
##### 3. Add your file to the app
In [`./src/utils/languages.js`](https://github.com/Lissy93/dashy/tree/master/src/utils/languages.js), you need to do 2 small things:
First import your new translation file, do this at the top of the page.
E.g. `import de from '@/assets/locales/de.json';`
Second, add it to the array of languages, e.g:
```javascript
export const languages = [
{
name: 'English',
code: 'en',
locale: en,
flag: '🇬🇧',
},
{
name: 'German', // The name of your language
code: 'de', // The ISO code of your language
locale: de, // The name of the file you imported (no quotes)
flag: '🇩🇪', // An optional flag emoji
},
];
```
You can also add your new language to the readme, under the [Language Switching](https://github.com/Lissy93/dashy#language-switching-) section and optionally include your name/ username if you'd like to be credited for your work. Done!
If you are not comfortable with making pull requests, or do not want to modify the code, then feel free to instead send the translated file to me, and I can add it into the application. I will be sure to credit you appropriately.
---
## Adding Text
If you're working on a new component, then any text that is displayed to the user should be extracted out of the component, and stored in the file. This also applies to any existing components, that might have been forgotten to be translated.
Thankfully, everything is already setup, and so is as easy as adding text to the JSON file, and pasting the key to that text in your component.
#### 1. Add Translated Text
Firstly, go to [`./src/assets/locales/en.json`](https://github.com/Lissy93/dashy/blob/master/src/assets/locales/en.json), and either find the appropriate section, or create a new section. Lets say you're new component is called `my-widget`, you could add `"my-widget": {}` to store all your text as key-value-pairs. E.g.
```json
"my-widget": {
"awesome-text": "I am some text, that will be seen by the user"
}
```
Note that you **must** add English translations for all text. Missing languages are not a problem, as they will always fallback to Enslish, but if the English is missing, then nothing can be displayed.
#### 2. Use Text within Component
Once your text is in the translation file, you can now use it within your component. There is a global `$t` function, with takes the key of your new translation, and returns the value. For example:
```vue
<p>{{ $t('my-widget.awesome-text') }}</p>
```
Note that the `{{ }}` just tells Vue that this is JavaScript/ dynamic.
This will render: `<p>I am some text, that will be seen by the user</p>`
If you need to display text programmatically, from within the components JavaScript (e.g. in a toast popup), then use `this.$t`.
For example: `alert(this.$t('my-widget.awesome-text'))`.
You may also need to pass a variable to be displayed within a translation. Vue I18n supports [Interpolations](https://vue-i18n.intlify.dev/guide/essentials/syntax.html#interpolations) using mustache-like syntax.
For example, you would set your translation to:
```json
{
"welcome-message": "Hello {name}!"
}
```
And then pass that variable (`name`) within a JSON object as the second parameter on `$t`, like:
```javascript
$t('welcome-message', { name: 'Alicia' })
```
Which will render:
```text
Hello Alicia!
```
There are many other advanced features, including Pluralization, Datetime & Number Formatting, Message Support and more, all of which are outlined in the [Vue-i18n Docs](https://vue-i18n.intlify.dev/guide/).
#### Basic Example
Using the search bar as an example, this would look something like:
In [`./src/components/Settings/SearchBar.vue`](https://github.com/Lissy93/dashy/blob/master/src/components/Settings/SearchBar.vue):
```vue
<template>
<form>
<label for="search-input">{{ $t('search.search-label') }}</label>
<input
id="search-input"
v-model="searchValue"
:placeholder="$t('search.search-placeholder')"
/>
</form>
</template>
```
Then in [`./src/assets/locales/en.json`](https://github.com/Lissy93/dashy/blob/master/src/assets/locales/en.json):
```json
{
"search": {
"search-label": "Search",
"search-placeholder": "Start typing to filter",
},
...
}
```

View File

@ -1,110 +0,0 @@
# Privacy & Security
Dashy was built with privacy in mind. Self-hosting your own apps and services is a great way to protect yourself from the mass data collection employed by big tech companies, and Dashy was designed to keep your local services organized and accessible from a single place.
It's fully open source, and I've tried to keep to code as clear and thoroughly documented as possible, which will make it easy for you to understand exactly how it works, and what goes on behind the scenes.
For privacy and security tips, check out another project of mine: **[Personal Security Checklist](https://github.com/Lissy93/personal-security-checklist)**.
---
## External Requests
By default, Dashy will not make any external requests, unless you configure it to. Some features (which are all off by default) do require internat access, and this section outlines those features, the services used, and links to their privacy policies.
### Font Awesome
If either any of your sections or items are using font-awesome icons, then these will be fetched directly from font-awesome on page load. See the [Font Awesome Privacy Policy](https://fontawesome.com/privacy) for more info.
### Favicon Fetching
If an item's icon is set to `favicon`, then it will be auto-fetched from the corresponding URL. Since not all websites have their icon located at `/favicon.ico`, and if they do, it's often very low resolution (like `16 x 16 px`). Therefore, the default behavior is for Dashy to check if the URL is public, and if so will use an API to fetch the favicon. For self-hosted services, the favion will be fetched from the default path, and no external requests will be made.
The default favicon API is [Favicon Kit](https://faviconkit.com/), but this can be changed by setting `appConfig.faviconApi` to an alternate source (`google`, `clearbit`, `webmasterapi` and `allesedv` are supported). If you do not want to use any API, then you can set this property to `local`, and the favicon will be fetched from the default path. For hosted services, this will still incur an external request.
### Other Icons
Section icons, item icons and app icons are able to accept a URL to a raw image, if the image is hosted online then an external request will be made. To avoid the need to make external requests for icon assets, you can either use a self-hosted CDN, or store your images within `./public/item-icons` (which can be mounted as a volume if you're using Docker).
### Web Assets
By default, all assets required by Dashy come bundled within the source, and so no external requests are made. If you add an additional font, which is imported from a CDN, then that will incur an external request. The same applies for other web assets, like external images, scripts or styles.
### Status Checking
The status check util will ping your services directly, and does not rely on any third party. If you are checking the uptime status of a public/ hosted application, then please refer to that services privacy policy. For all self-hosted services, requests happen locally within your network, and are not external.
### Update Checks
When the application loads, it checks for updates. The results of which are displayed in the config menu of the UI. This was implemented because using a very outdated version of Dashy may have unfixed issues. Your version is fetched from the source (local request), but the latest version is fetched from GitHub, which is an external request. This can be disabled by setting `appConfig.disableUpdateChecks: true`
### Anonymous Error Reporting
Error reporting is disabled by default, and no data will ever be sent without your explicit consent. In fact, the error tracking method will not even be imported unless you have actively enabled it. [Sentry](https://github.com/getsentry/sentry) is used for this, it's an open source error tracking and performance monitoring tool, which is used to identify any issues which occur in the production app (if you enable it).
The crash report includes the file or line of code that triggered the error, and a 2-layer deep stack trace. Reoccurring errors will also include the following user information: OS type (Mac, Windows, Linux, Android or iOS) and browser type (Firefox, Chrome, IE, Safari). Data scrubbing is enabled. IP address will not be stored. If any potentially identifiable data ever finds its way into a crash report, it will be automatically and permanently erased. All statistics collected are anonomized and stored securely, and ae automatically deleted after 14 days. For more about privacy and security, see the [Sentry Docs](https://sentry.io/security/).
Enabling anonymous error reporting helps me to discover bugs I was unaware of, and then fix them, in order to make Dashy more reliable long term. Error reporting is activated by setting `appConfig.enableErrorReporting: true`.
If you need to monitor bugs yourself, then you can [self-host your own Sentry Server](https://develop.sentry.dev/self-hosted/), and use it by setting `appConfig.sentryDsn` to your Sentry instances [Data Source Name](https://docs.sentry.io/product/sentry-basics/dsn-explainer/), then just enable error reporting in Dashy.
---
## Local Storage
In order for user preferences to be persisted between sessions, certain data needs to be stored in the browsers local storage. No personal info is kept here, none of this data can be accessed by other domains, and no data is ever sent to any server without your prior consent.
You can view your browsers session storage by opening up the dev tools (F12) --> Application --> Storage.
The following section outlines all data that is stored in the browsers, as cookies or local storage.
#### Cookies
- `AUTH_TOKEN` - A unique token, generated from a hash of users credentials, to verify they are authenticated. Only used when auth is enabled
#### Local Storage
- `LANGUAGE` - The locale to show app text in
- `HIDE_WELCOME_BANNER` - Set to true once user dismissed welcome message, so that it's not shown again
- `LAYOUT_ORIENTATION` - Preferred section layout, either horizontal, vertical or auto
- `COLLAPSE_STATE` - Remembers which sections are collapsed
- `ICON_SIZE` - Size of items, either small, medium or large
- `THEME: 'theme` - Users applied theme
- `CUSTOM_COLORS` - Any color modifications made to a given theme
- `BACKUP_ID` - If a backup has been made, the ID is stored here
- `BACKUP_HASH` - A unique hash of the previous backups meta data
- `HIDE_SETTINGS` - Lets user hide or show the settings menu
- `USERNAME` - If user logged in, store username in order to welcome them
- `CONF_SECTIONS` - Array of sections, only used when user applies changes locally
- `PAGE_INFO` - Config page info, only used when user applies changes locally
- `APP_CONFIG` - App config, only used when user applies changes locally
---
## Dependencies
As with most web projects, Dashy relies on several [dependencies](https://github.com/Lissy93/dashy/blob/master/docs/credits#dependencies-). For links to each, and a breakdown of their licenses, please see [Legal](https://github.com/Lissy93/dashy/blob/master/.github/LEGAL).
Dependencies can introduce security vulnerabilities, but since all these packages are open source any issues are usually very quickly spotted. Dashy is using Snyk for dependency security monitoring, and you can see [the latest report here](https://snyk.io/test/github/lissy93/dashy). If any issue is detected by Snyk, a note about it will appear at the top of the Reamde, and will usually be fixed within 48 hours.
Note that packages listed under `deDependencies` section are only used for building the project, and are not included in the production environment.
---
## Securing your Environment
Running your self-hosted applications in individual, containerized environments (such as containers or VMs) helps keep them isolated, and prevent an exploit in one service effecting another.
There is very little complexity involved with Dashy, and therefore the attack surface is reasonably small, but it is still important to follow best practices and employ monitoring for all your self-hosted apps. A couple of things that you should look at include:
- Use SSL for securing traffic in transit
- Configure [authentication](/docs/authentication#alternative-authentication-methods) to prevent unauthorized access
- Keep your system, software and Dashy up-to-date
- Ensure your server is appropriately secured
- Manage users and SSH correctly
- Enable and configure firewall rules
- Implement security, malware and traffic scanning
- Setup malicious traffic detection
- Understand the [Docker attack fronts](https://docs.docker.com/engine/security/), and follow [Docker Security Best Practices](https://snyk.io/blog/10-docker-image-security-best-practices/)
This is covered in more detail in [App Management](/docs/management).
---
## Reporting a Security Issue
If you think you've found a critical issue with Dashy, please send an email to `security@mail.alicia.omg.lol`. You can encrypt it, using [`0688 F8D3 4587 D954 E9E5 1FB8 FEDB 68F5 5C02 83A7`](https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7). You should receive a response within 48 hours.
All non-critical issues can be raised as a ticket.
Please include the following information:
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue

View File

@ -1,128 +0,0 @@
# Quick Start
Welcome to Dashy! So glad you're here 😊 In a couple of minutes, you'll have your new dashboard up and running 🚀
**TDLR;** Run `docker run -p 8080:80 lissy93/dashy`, then open `http://localhost:8080`
---
## 1. Prerequisites
The quickest and easiest method of running Dashy is using Docker (or another container engine). You can find installation instructions for your system in the [Docker Documentation](https://docs.docker.com/get-docker/).
If you don't want to use Docker, then you can use one of Dashy's other supported installation methods instead, all of which are outlined in the [Deployment Docs](https://github.com/Lissy93/dashy/blob/master/docs/deployment).
---
## 2. Installation
To pull the latest image, and build and start the app run:
```
docker run -d \
-p 8080:80 \
--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#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#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
---
## 3. Configure
Now that you've got Dashy running, you are going to want to set it up with your own content.
Config is written in [YAML Format](https://yaml.org/), and saved in [`/public/conf.yml`](https://github.com/Lissy93/dashy/blob/master/public/conf.yml).
The format on the config file is pretty straight forward. There are three root attributes:
- [`pageInfo`](https://github.com/Lissy93/dashy/blob/master/docs/configuring#pageinfo) - Dashboard meta data, like title, description, nav bar links and footer text
- [`appConfig`](https://github.com/Lissy93/dashy/blob/master/docs/configuring#appconfig-optional) - Dashboard settings, like themes, authentication, language and customization
- [`sections`](https://github.com/Lissy93/dashy/blob/master/docs/configuring#section) - An array of sections, each including an array of items
You can view a full list of all available config options in the [Configuring Docs](https://github.com/Lissy93/dashy/blob/master/docs/configuring).
```yaml
pageInfo:
title: Home Lab
sections: # An array of sections
- name: Example Section
icon: far fa-rocket
items:
- title: GitHub
description: Dashy source code and docs
icon: fab fa-github
url: https://github.com/Lissy93/dashy
- title: Issues
description: View open issues, or raise a new one
icon: fas fa-bug
url: https://github.com/Lissy93/dashy/issues
- name: Local Services
items:
- title: Firewall
icon: favicon
url: http://192.168.1.1/
- title: Game Server
icon: https://i.ibb.co/710B3Yc/space-invader-x256.png
url: http://192.168.130.1/
```
Notes:
- You can use a Docker volume to pass a config file from your host system to the container
- E.g. `-v ./host-system/my-local-conf.yml:/app/public/conf.yml`
- It's also possible to edit your config directly through the UI, and changes will be saved in this file
- Check your config against Dashy's schema, with `docker exec -it [container-id] yarn validate-config`
- You might find it helpful to look at some examples, a collection of which can be [found here](https://gist.github.com/Lissy93/000f712a5ce98f212817d20bc16bab10)
- After editing your config, the app will rebuild in the background, which may take a minute
---
## 4. Further Customisation
Once you've got Dashy setup, you'll want to ensure the container is properly healthy, secured, backed up and kept up-to-date. All this is covered in the [Management Docs](https://github.com/Lissy93/dashy/blob/master/docs/management).
You might also want to check out the docs for specific features you'd like to use:
- [Authentication](/docs/authentication) - Setting up authentication to protect your dashboard
- [Backup & Restore](/docs/backup-restore) - Guide to Dashy's cloud sync feature
- [Icons](/docs/icons) - Outline of all available icon types for sections and items
- [Localisation](/docs/multi-language-support) - How to change language, or add your own
- [Status Indicators](/docs/status-indicators) - Using Dashy to monitor uptime and status of your apps
- [Theming](/docs/theming) - Complete guide to applying, writing and modifying themes and styles
---
## 5. Final Note
If you're enjoying Dashy, and have a few minutes to spare, please do take a moment to look at the [Contributing Page](https://github.com/Lissy93/dashy/blob/master/docs/contributing). There are a few things that we really need some help with, and whatever your skill set, there are ways you can help out. Any contributions, however small would be greatly appreciated.
Thank you to [everyone](https://github.com/Lissy93/dashy/blob/master/docs/credits) who is already doing so, without developing and maintaining Dashy would not have been so possible.
You can also consider sharing your dashboard in the [Showcase](https://github.com/Lissy93/dashy/blob/master/docs/showcase), to help provide inspiration for others.
For more info, check out the [Documentation](https://github.com/Lissy93/dashy/tree/master/docs#readme). If you've got any questions feel free to ask in the [Discussion](https://github.com/Lissy93/dashy/discussions), and if you think you've found a bug you can [raise an issue](https://github.com/Lissy93/dashy/issues/new/choose) to get it fixed.
Enjoy your dashboard :)
---
## Alternative Deployment Method 1 - From Source
You can also easily run the app on your system without Docker. For this [Git](https://git-scm.com/downloads), [Node.js](https://nodejs.org/), and [Yarn](https://yarnpkg.com/) are required.
```
git clone https://github.com/Lissy93/dashy.git && cd dashy
yarn # Install dependencies
yarn build # Build the app
yarn start # Start the app
```
Then edit `./public/conf.yml` and rebuild the app with `yarn build`
---
## Alternative Deployment Method 2 - Netlify
Don't have a server? No problem! You can run Dashy for free on Netlify (as well as many [other cloud providers](/docs/deployment#deploy-to-cloud-service)). All you need it a GitHub account.
1. Fork Dashy's repository on GitHub
2. [Log in](app.netlify.com/login/) to Netlify with GitHub
3. Click "New site from Git" and select your forked repo, then click **Deploy**!
4. You can then edit the config in `./public/conf.yml` in your repo, and Netlify will rebuild the app

View File

@ -1,32 +0,0 @@
![Dashy Docs](https://i.ibb.co/4mdNf7M/heading-docs.png)
### Running Dashy
- [Quick Start](/docs/quick-start) - TDLR guide on getting Dashy up and running
- [Deployment](/docs/deployment) - Full guide on deploying Dashy either locally or online
- [Configuring](/docs/configuring) - Complete list of all available options in the config file
- [App Management](/docs/management) - Managing your app, updating, security, web server configuration, etc
- [Troubleshooting](/docs/troubleshooting) - Common errors and problems, and how to fix them
### Development and Contributing
- [Developing](/docs/developing) - Running Dashy development server locally, and general workflow
- [Development Guides](/docs/development-guides) - Common development tasks, to help new contributors
- [Contributing](/docs/contributing) - How you can help keep Dashy alive
- [Showcase](/docs/showcase) - See how others are using Dashy, and share your dashboard
- [Credits](/docs/credits) - List of people and projects that have made Dashy possible
### Feature Docs
- [Authentication](/docs/authentication) - Guide to setting up authentication to protect your dashboard
- [Alternate Views](/docs/alternate-views) - Outline of available pages / views and item opening methods
- [Backup & Restore](/docs/backup-restore) - Guide to Dashy's cloud sync feature
- [Icons](/docs/icons) - Outline of all available icon types for sections and items
- [Language Switching](/docs/multi-language-support) - Details on how to switch language, or add a new locale
- [Status Indicators](/docs/status-indicators) - Using Dashy to monitor uptime and status of your apps
- [Searching & Shortcuts](/docs/searching) - Finding and launching your apps, and using keyboard shortcuts
- [Theming](/docs/theming) - Complete guide to applying, writing and modifying themes and styles
### Misc
- [Privacy & Security](/docs/privacy) - List of requests, potential issues, and security resources
- [License](/LICENSE) - Copy of the MIT License
- [Legal](/.github/LEGAL) - Licenses of direct dependencies
- [Code of Conduct](/.github/CODE_OF_CONDUCT) - Contributor Covenant Code of Conduct
- [Changelog](/.github/CHANGELOG) - Details of recent changes, and historical versions

View File

@ -1,83 +0,0 @@
# Keyboard Shortcuts
## Searching
One of the primary purposes of Dashy is to allow you to quickly find and launch a given app. To make this as quick as possible, there is no need to touch the mouse, or press a certain key to begin searching - just start typing. Results will be filtered in real-time. No need to worry about case, special characters or small typos, these are taken care of, and your results should appear.
## Navigating
You can navigate through your items or search results using the keyboard. You can use <kbd>Tab</kbd> to cycle through results, and <kbd>Shift</kbd> + <kbd>Tab</kbd> to go backwards. Or use the arrow keys, <kbd></kbd>, <kbd></kbd>, <kbd></kbd> and <kbd></kbd>.
## Launching Apps
You can launch a elected app by hitting <kbd>Enter</kbd>. This will open the app using your default opening method, specified in `target` (either `newtab`, `sametab`, `modal` or `workspace`). You can also use <kbd>Alt</kbd> + <kbd>Enter</kbd> to open the app in a pop-up modal, or <kbd>Ctrl</kbd> + <kbd>Enter</kbd> to open it in a new tab. For all available opening methods, just right-click on an item, to bring up the context menu.
## Tags
By default, items are filtered by the `title` attribute, as well as the hostname (extracted from `url`), the `provider` and `description`. If you need to find results based on text which isn't included in these attributes, then you can add `tags` to a given item.
```yaml
items:
- title: Plex
description: Media library
icon: favicon
url: https://plex.lab.local
tags: [ movies, videos, music ]
- title: FreshRSS
description: RSS Reader
icon: favicon
url: https://freshrss.lab.local
tags: [ news, updates, blogs ]
```
In the above example, Plex will be visible when searching for 'movies', and FreshRSS with 'news'
## Custom Hotkeys
For apps that you use regularly, you can set a custom keybinding. Use the `hotkey` parameter on a certain item to specify a numeric key, between `0 - 9`. You can then launch that app, by just pressing that key, which is much quicker than searching for it, if it's an app you use frequently.
```yaml
- title: Bookstack
icon: far fa-books
url: https://bookstack.lab.local/
hotkey: 2
- title: Git Tea
icon: fab fa-git
url: https://git.lab.local/
target: workspace
hotkey: 3
```
In the above example, pressing <kbd>2</kbd> will launch Bookstack. Or hitting <kbd>3</kbd> will open Git in the workspace view.
## Web Search
It's possible to search the web directly from Dashy, which might be useful if you're using Dashy as your start page. This can be done by typing your query as normal, and then pressing <kbd></kbd>. Web search options are configured under `appConfig.webSearch`.
#### Setting Search Engine
Set your default search engine using the `webSearch.searchEngine` property. This defaults to DuckDuckGo. Search engine must be referenced by their key, the following providers are supported:
- [`duckduckgo`](https://duckduckgo.com), [`google`](https://google.com), [`whoogle`](https://whoogle.sdf.org), [`qwant`](https://www.qwant.com), [`startpage`](https://www.startpage.com), [`searx-bar`](https://searx.bar), [`searx-info`](https://searx.info)
- [`searx-tiekoetter`](https://searx.tiekoetter.com), [`searx-bissisoft`](https://searx.bissisoft.com), [`ecosia`](https://www.ecosia.org), [`metager`](https://metager.org/meta), [`swisscows`](https://swisscows.com), [`mojeek`](https://www.mojeek.com)
- [`wikipedia`](https://en.wikipedia.org), [`wolframalpha`](https://www.wolframalpha.com), [`stackoverflow`](https://stackoverflow.com), [`github`](https://github.com), [`reddit`](https://www.reddit.com), [`youtube`](https://youtube.com), [`bbc`](https://www.bbc.co.uk)
#### Using Custom Search Engine
You can also use a custom search engine, that isn't included in the above list (like a self-hosted instance of [Whoogle](https://github.com/benbusby/whoogle-search) or [Searx](https://searx.github.io/searx/)). Set `searchEngine: custom`, and then specify the URL (plus query params) to you're search engine under `customSearchEngine`.
For example:
```yaml
appConfig:
webSearch:
searchEngine: custom
customSearchEngine: 'https://searx.local/search?q='
```
#### Setting Opening Method
In a similar way to opening apps, you can specify where you would like search results to be opened. This is done under the `openingMethod` attribute, and can be set to either `newtab`, `sametab` or `workspace`. By default results are opened in a new tab.
#### Disabling Web Search
Web search can be disabled, by setting `disableWebSearch`, for example:
```yaml
appConfig:
webSearch: { disableWebSearch: true }
```
## Clearing Search
You can clear your search term at any time, by pressing <kbd>Esc</kbd>.
This can also be used to close an open pop-up modal.

View File

@ -1,98 +0,0 @@
# User Showcase
| 💗 Do you use Dashy? Got a sweet dashboard? Submit it to the showcase! 👉 [See How](#submitting-your-dashboard) |
|-|
### Home Lab 2.0
![screenshot-homelab](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/1-home-lab-material.png)
---
### Networking Services
> By [@Lissy93](https://github.com/lissy93)
![screenshot-networking-services](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/2-networking-services-minimal-dark.png)
---
### Homelab & VPS dashboard
> By [@shadowking001](https://github.com/shadowking001)
![screenshot-shadowking001-dashy](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/8-shadowking001s-dashy.png)
---
### NAS Home Dashboard
> By [@cerealconyogurt](https://github.com/cerealconyogurt)
![screenshot-networking-services](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/6-nas-home-dashboard.png)
---
### Dashy Live
> By [@Lissy93](https://github.com/lissy93)
> A dashboard I made to manage all project development links from one place
![screenshot-dashy-live](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/10-dashy-live.png)
### CFT Toolbox
![screenshot-cft-toolbox](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/3-cft-toolbox.png)
---
### Bookmarks
![screenshot-bookmarks](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/4-bookmarks-colourful.png)
---
### Project Management
![screenshot-project-managment](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/5-project-managment.png)
---
### Ground Control
> By [@dtctek](https://github.com/dtctek)
![screenshot-ground-control](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/7-ground-control-dtctek.png)
---
### Yet Another Homelab
![screenshot-yet-another-homelab](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/showcase/9-home-lab-oblivion.png)
---
## Submitting your Dashboard
#### How to Submit
- [Open an Issue](https://git.io/JEtgM)
- [Open a PR](https://github.com/Lissy93/dashy/compare)
#### What to Include
Please include the following information:
- A single high-quality screenshot of your Dashboard
- A short title (it doesn't have to be particularly imaginative)
- An optional description, you could include details on anything interesting or unique about your dashboard, or say how you use it, and why it's awesome
- Optionally leave your name or username, with a link to your GitHub, Twitter or Website
#### Template
If you're submitting a pull request, please use a format similar to this:
```
### [Dashboard Name] (required)
> Submitted by [@username](https://github.com/user) (optional)
![dashboard-screenshot](/docs/showcase/screenshot-name.jpg) (required)
[An optional text description, or any interesting details] (optional)
---
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,2 +0,0 @@
See: [Showcase](/docs/showcase).

View File

@ -1,83 +0,0 @@
# Status Indicators
Dashy has an optional feature that can display a small icon next to each of your running services, indicating it's current status. This can be 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. The status feature will show response time, response code, online/ offline check and if applicable, a relevant error message
<p align="center">
<img width="800" src="/docs/assets/status-check-demo.gif" />
</p>
## Enabling Status Indicators
By default, this feature is off. If you do not want this feature, just don't add the `statusCheck` to your conf.yml file, then no requests will be made.
To enable status checks, you can either turn it on for all items, by setting `appConfig.statusCheck: true`, like:
```yaml
appConfig:
statusCheck: true
```
Or you can enable/ disable it on a per-item basis, with the `item[n].statusCheck` attribute
```yaml
sections:
- name: Firewall
items:
- title: OPNsense
description: Firewall Central Management
icon: networking/opnsense.png
url: https://192.168.1.1
statusCheck: false
- title: MalTrail
description: Malicious traffic detection system
icon: networking/maltrail.png
url: http://192.168.1.1:8338
statusCheck: true
- title: Ntopng
description: Network traffic probe and network use monitor
icon: networking/ntop.png
url: http://192.168.1.1:3001
statusCheck: true
```
## Continuous Checking
By default, with status indicators enabled Dashy will check an applications status on page load, and will not keep indicators updated. This is usually desirable behavior. However, if you do want the status indicators to continue to poll your running services, this can be enabled by setting the `statusCheckInterval` attribute. Here you define an interval as an integer in seconds, and Dashy will poll your apps every x seconds. Note that if this number is very low (below 5 seconds), you may notice the app running slightly slower.
The following example, will instruct Dashy to continuously check the status of your services every 20 seconds
```
appConfig:
statusCheck: true
statusCheckInterval: 20
```
## Using a Different Endpoint
By default, the status checker will use the URL of each application being checked. In some situations, you may want to use a different endpoint for status checking. Similarly, some services provide a dedicated path for uptime monitoring.
You can set the `statusCheckUrl` property on any given item in order to do this. The status checker will then ping that endpoint, instead of the apps main `url` property.
## Setting Custom Headers
If your service is responding with an error, despite being up and running, it is most likely because custom headers for authentication, authorization or encoding are required. You can define these headers under the `statusCheckHeaders` property for any service. It should be defined as an object format, with the name of header as the key, and header content as the value.
For example, `statusCheckHeaders: { 'X-Custom-Header': 'foobar' }`
## Disabling Security
By default, (if you're using HTTPS) any requests to insecure or non-HTTPS content will be blocked. This will cause the status check to fail. If you trust the endpoint (e.g. you're self-hosting it), then you can disable this security measure for an individual item. This is done by setting `statusCheckAllowInsecure: true`
## Troubleshooting Failing Status Checks
If the status is always returning an error, despite the service being online, then it is most likely an issue with access control, and should be fixed with the correct headers. Hover over the failing status to see the error code and response, in order to know where to start with addressing it.
If your service requires requests to include any authorization in the headers, then use the `statusCheckHeaders` property, as described above.
If you are still having issues, it may be because your target application is blocking requests from Dashy's IP. This is a [CORS error](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), and can be fixed by setting the headers on your target app, to include:
```
Access-Control-Allow-Origin: https://location-of-dashy/
Vary: Origin
```
If the URL you are checking is not using HTTPS, then you may need to disable the rejection of insecure requests. This can be done by setting `statusCheckAllowInsecure` to true for a given item.
If you're serving Dashy though a CDN, instead of using the Node server or Docker image, then the Node endpoint that makes requests will not be available to you, and all requests will fail. A workaround for this may be implemented in the future, but in the meantime, your only option is to use the Docker or Node deployment method.
For further troubleshooting, use an application like [Postman](https://postman.com) to diagnose the issue.
## How it Works
When the app is loaded, if `appConfig.statusCheck: true` is set, or if any items have the `statusCheck: true` enabled, then Dashy will make a request, to `https://[your-host-name]/ping?url=[address-or-servce]` (may al include GET params for headers and the secure flag), which in turn will ping that running service, and respond with a status code. Response time is calculated from the difference between start and end time of the request.
When the response completes, an indicator will display next to each item. The color denotes the status: Yellow while waiting for the response to return, green if request was successful, red if it failed, and grey if it was unable to make the request all together.
All requests are made straight from your server, there is no intermediary. So providing you are hosting Dashy yourself, and are checking the status of other self-hosted services, there shouldn't be any privacy concerns. Requests are made asynchronously, so this won't have any significant impact on page load speeds. However recurring requests (using `statusCheckInterval`) may run more slowly if the interval between requests is very short.

View File

@ -1,187 +0,0 @@
# Theming
By default Dashy comes with 20 built in themes, which can be applied from the dropwodwn menu in the UI
![Built-in Themes](https://i.ibb.co/GV3wRss/Dashy-Themes.png)
You can also add your own themes, apply custom styles, and modify colors.
You can customize Dashy by writing your own CSS, which can be loaded either as an external stylesheet, set directly through the UI, or specified in the config file. Most styling options can be set through CSS variables, which are outlined below.
The following content requires that you have a basic understanding of CSS. If you're just beginning, you may find [this article](https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps) helpful.
### How Theme-Switching Works
The theme switching is done by simply changing the `data-theme` attribute on the root DOM element, which can then be targeted by CSS. First off, in order for the theme to show up in the theme switcher, it needs to be added to the config file, under `appConfig.cssThemes`, either as a string, or an array of strings for multiple themes. For example:
```yaml
appConfig:
cssThemes: ['tiger', 'another-theme']
```
You can now create a block to target you're theme with `html[data-theme='my-theme']{}` and set some styles. The easiest method is by setting CSS variables, but you can also directly override elements by their selector. As an example, see the [built-in CSS themes](https://github.com/Lissy93/dashy/blob/master/src/styles/color-themes.scss).
```css
html[data-theme='tiger'] {
--primary: #f58233;
--background: #0b1021;
}
```
Finally, from the UI use the theme dropdown menu to select your new theme, and your styles will be applied.
You can also set `appConfig.theme` to pre-select a default theme, which will be applied immediately after deployment.
### Modifying Theme Colors
Themes can be modified either through the UI, using the color picker menu (to the right of the theme dropdown), or directly in the config file, under `appConfig.customColors`. Here you can specify the value for any of the [available CSS variables](#css-variables).
<p align="center">
<a href="https://i.ibb.co/cLDXj1R/dashy-theme-configurator.gif">
<img alt="Example Themes" src="https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/theme-config-demo.gif" width="400" />
</a>
</p>
By default, any color modifications made to the current theme through the UI will only be applied locally. If you need these settings to be set globally, then click the 'Export' button, to get the color codes and variable names, which can then be backed up, or saved in your config file.
Custom colors are saved relative the the base theme selected. So if you switch themes after setting custom colors, then you're settings will no longer be applied. You're changes are not lost though, and switching back to the original theme will see your styles reapplied.
If these values are specified in your `conf.yml` file, then it will look something like the below example. Note that in YAML, values or keys which contain special characters, must be wrapped in quotes.
```yaml
appConfig:
customColors:
oblivion:
primary: '#75efff'
background: '#2a3647'
dracula:
primary: '#8be9fd'
```
### Adding your own Theme
User-defined styles and custom themes should be defined in `./src/styles/user-defined-themes.scss`. If you're using Docker, you can pass your own stylesheet in using the `--volume` flag. E.g. `v ./my-themes.scss:/app/src/styles/user-defined-themes.scss`. Don't forget to pass your theme name into `appConfig.cssThemes` so that it shows up on the theme-switcher dropdown.
### Setting Custom CSS in the UI
Custom CSS can be developed, tested and applied directly through the UI. Although you will need to make note of your changes to apply them across instances.
This can be done from the Config menu (spanner icon in the top-right), under the Custom Styles tab. This is then associated with `appConfig.customCss` in local storage. Styles can also be directly applied to this attribute in the config file, but this may get messy very quickly if you have a lot of CSS.
### Loading External Stylesheets
The URI of a stylesheet, either local or hosted on a remote CDN can be passed into the config file. The attribute `appConfig.externalStyleSheet` accepts either a string, or an array of strings. You can also pass custom font stylesheets here, they must be in a CSS format (for example, `https://fonts.googleapis.com/css2?family=Cutive+Mono`).
This is handled in [`ThemeHelper.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/ThemeHelper.js).
For example:
```yaml
appConfig:
externalStyleSheet: 'https://example.com/my-stylesheet.css'
```
```yaml
appConfig:
externalStyleSheet: ['/themes/my-theme-1.css', '/themes/my-theme-2.css']
```
### Hard-Coding Section or Item Colors
Some UI components have a color option, that can be set in the config file, to force the color of a given item or section no matter what theme is selected. These colors should be expressed as hex codes (e.g. `#fff`) or HTML colors (e.g. `red`). The following attributes are supported:
- `section.color` - Custom color for a given section
- `item.color` - Font and icon color for a given item
- `item.backgroundColor` - Background color for a given icon
### Typography
Essential fonts bundled within the app are located within `./src/assets/fonts/`. All optional fonts that are used by themes are stored in `./public/fonts/`, if you want to add your own font, this is where you should put it. As with assets, if you're using Docker then using a volume to link a directory on your host system with this path within the container will make management much easier.
Fonts which are not being used by the current theme are **not** fetched on page load. They are instead only loaded into the application if and when they are required. So having multiple themes with various typefaces shouldn't have any negative impact on performance.
Full credit to the typographers behind each of the included fonts. Specifically: Matt McInerney, Christian Robertson, Haley Fiege, Peter Hull, Cyreal and the legendary Vernon Adams
### CSS Variables
All colors as well as other variable values (such as borders, border-radius, shadows) are specified as CSS variables. This makes theming the application easy, as you only need to change a given color or value in one place. You can find all variables in [`color-palette.scss`](https://github.com/Lissy93/dashy/blob/master/src/styles/color-palette.scss) and the themes which make use of these color variables are specified in [`color-themes.scss`](https://github.com/Lissy93/dashy/blob/master/src/styles/color-themes.scss)
CSS variables are simple to use. You define them like: `--background: #fff;` and use them like: `body { background-color: var(--background); }`. For more information, see this guide on using [CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties).
You can determine the variable used by any given element, and visualize changes using the browser developer tools (Usually opened with `F12`, or Options --> More --> Developer Tools). Under the elements tab, click the Element Selector icon (usually top-left corner), you will then be able to select any DOM element on the page by hovering and clicking it. In the CSS panel you will see all styles assigned to that given element, including CSS variables. Click a variable to see it's parent value, and for color attributes, click the color square to modify the color. For more information, see this [getting started guide](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools), and these articles on [selecting elements](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Select_an_element) and [inspecting and modifying colors](https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Inspect_and_select_colors).
#### Top-Level Variables
These are all that are required to create a theme. All other variables inherit their values from these variables, and can optionally be overridden.
- `--primary` - Application primary color. Used for title, text, accents, and other features
- `--background` - Application background color
- `--background-darker` - Secondary background color (usually darker), used for navigation bar, section fill, footer etc
- `--curve-factor` - The border radius used globally throughout the application. Specified in `px`, defaults to `5px`
- `--dimming-factor` - Inactive elements have slight transparency. This can be between `0` (invisible) and `1` (normal), defaults to `0.7`
#### Targeted Color Variables
You can target specific elements on the UI with these variables. All are optional, since by default, they inherit their values from above
- `--heading-text-color` - Text color for web page heading and sub-heading. Defaults to `--primary`
- `--nav-link-text-color` - The text color for links displayed in the navigation bar. Defaults to `--primary`
- `--nav-link-background-color` - The background color for links displayed in the navigation bar
- `--nav-link-text-color-hover` - The text color when a navigation bar link is hovered over. Defaults to `--primary`
- `--nav-link-background-color-hover` - The background color for nav bar links when hovered over
- `--nav-link-border-color` - The border color for nav bar links. Defaults to `transparent`
- `--nav-link-border-color-hover` - The border color for nav bar links when hovered over. Defaults to `--primary`
- `--search-container-background` - Background for the container containing the search bar. Defaults to `--background-darker`
- `--search-field-background` - Fill color for the search bar. Defaults to `--background`
- `--settings-background` - The background for the quick settings. Defaults to `--background`
- `--settings-text-color` - The text and icon color for quick settings. Defaults to `--primary`
- `--footer-text-color` - Color for text within the footer. Defaults to `--medium-grey`
- `--footer-text-color-link` - Color for any hyperlinks within the footer. Defaults to `--primary`
- `--item-text-color` - The text and icon color for items. Defaults to `--primary`
- `--item-group-outer-background` - The background color for the outer part of a section (including section head). Defaults to `--primary`
- `--item-group-background` - The background color for the inner part of item groups. Defaults to `#0b1021cc` (semi-transparent black)
- `--item-group-heading-text-color` - The text color for section headings. Defaults to `--item-group-background`;
- `--item-group-heading-text-color-hover` - The text color for section headings, when hovered. Defaults to `--background`
- `--config-code-background` - Background color for the JSON editor in the config menu. Defaults to `#fff` (white)
- `--config-code-color` - Text color for the non-highlighted code within the JSON editor. Defaults to `--background`
- `--config-settings-color` - The background for the config/ settings pop-up modal. Defaults to `--primary`
- `--config-settings-background` - The text color for text within the settings container. Defaults to `--background-darker`
- `--scroll-bar-color` - Color of the scroll bar thumb. Defaults to `--primary`
- `--scroll-bar-background` Color of the scroll bar blank space. Defaults to `--background-darker`
- `--highlight-background` Fill color for text highlighting. Defaults to `--primary`
- `--highlight-color` Text color for selected/ highlighted text. Defaults to `--background`
- `--toast-background` - Background color for the toast info popup. Defaults to `--primary`
- `--toast-color` - Text, icon and border color in the toast info popup. Defaults to `--background`
- `--welcome-popup-background` - Background for the info pop-up shown on first load. Defaults to `--background-darker`
- `--welcome-popup-text-color` - Text color for the welcome pop-up. Defaults to `--primary`
- `--side-bar-background` - Background color of the sidebar used in the workspace view. Defaults to `--background-darker`
- `--side-bar-color` - Color of icons and text within the sidebar. Defaults to `--primary`
- `--status-check-tooltip-background` - Background color for status check tooltips. Defaults to `--background-darker`
- `--status-check-tooltip-color` - Text color for the status check tooltips. Defaults to `--primary`
- `--code-editor-color` - Text color used within raw code editors. Defaults to `--black`
- `--code-editor-background` - Background color for raw code editors. Defaults to `--white`
- `--context-menu-color` - Text color for right-click context menu over items. Defaults to `--primary`
- `--context-menu-background` - Background color of right-click context menu. Defaults to `--background`
- `--context-menu-secondary-color` - Border and outline color for context menu. Defaults to `--background-darker`
#### Non-Color Variables
- `--outline-color` - Used to outline focused or selected elements
- `--curve-factor-navbar` - The border radius of the navbar. Usually this is greater than `--curve-factor`
- `--scroll-bar-width` - Width of horizontal and vertical scroll bars. E.g. `8px`
- `--item-group-padding` - Inner padding of sections, determines the width of outline. E.g. `5px`
- `--item-shadow` - Shadow for items. E.g. `1px 1px 2px #130f23`
- `--item-hover-shadow` - Shadow for items when hovered over. E.g. `1px 2px 4px #373737`
- `--item-icon-transform` - A [transform](https://developer.mozilla.org/en-US/docs/Web/CSS/transform) property, to modify item icons. E.g. `drop-shadow(2px 4px 6px var(--transparent-50)) saturate(0.65)`
- `--item-icon-transform-hover` - Same as above, but applied when an item is hovered over. E.g. `drop-shadow(4px 8px 3px var(--transparent-50)) saturate(2)`
- `--item-group-shadow` - The shadow for an item group/ section. Defaults to `--item-shadow`
- `--settings-container-shadow` - A shadow property for the settings container. E.g. `none`
#### Action Colors
These colors represent intent, and so are not often changed, but you can do so if you wish
- `--info` - Information color, usually blue / `#04e4f4`
- `--success` - Success color, usually green / `#20e253`
- `--warning` - Warning color, usually yellow / `#f6f000`
- `--danger` - Error/ danger color, usually red / `#f80363`
- `--neutral` - Neutral color, usually grey / `#272f4d`
- `--white` - Just white / `#fff`
- `--black` - Just black / `#000`

View File

@ -1,137 +0,0 @@
# Troubleshooting
This document contains common problems and their solutions.
## `Refused to Connect` in Modal or Workspace View
This is not an issue with Dashy, but instead caused by the target app preventing direct access through embedded elements. It can be fixed by setting the [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) HTTP header set to `ALLOW [path to Dashy]` or `SAMEORIGIN`, as defined in [RFC-7034](https://datatracker.ietf.org/doc/html/rfc7034). These settings are usually set in the config file for the web server that's hosting the target application, here are some examples of how to enable cross-origin access with common web servers:
### NGINX
In NGINX, you can use the [`add_header`](https://nginx.org/en/docs/http/ngx_http_headers_module.html) module within the app block.
```
server {
...
add_header X-Frame-Options SAMEORIGIN always;
}
```
Then reload with `service nginx reload`
### Caddy
In Caddy, you can use the [`header`](https://caddyserver.com/docs/caddyfile/directives/header) directive.
```yaml
header {
X-Frame-Options SAMEORIGIN
}
```
### Apache
In Apache, you can use the [`mod_headers`](https://httpd.apache.org/docs/current/mod/mod_headers.html) module to set the `X-Frame-Options` in your config file. This file is usually located somewhere like `/etc/apache2/httpd.conf
```
Header set X-Frame-Options: "ALLOW-FROM http://[dashy-location]/"
```
---
## Yarn Error
For more info, see [Issue #1](https://github.com/Lissy93/dashy/issues/1)
First of all, check that you've got yarn installed correctly - see the [yarn installation docs](https://classic.yarnpkg.com/en/docs/install) for more info.
If you're getting an error about scenarios, then you've likely installed the wrong yarn... (you're [not](https://github.com/yarnpkg/yarn/issues/2821) the only one!). You can fix it by uninstalling, adding the correct repo, and reinstalling, for example, in Debian:
- `sudo apt remove yarn`
- `curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -`
- `echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list`
- `sudo apt update && sudo apt install yarn`
Alternatively, as a workaround, you have several options:
- Try using [NPM](https://www.npmjs.com/get-npm) instead: So clone, cd, then run `npm install`, `npm run build` and `npm start`
- Try using [Docker](https://www.docker.com/get-started) instead, and all of the system setup and dependencies will already be taken care of. So from within the directory, just run `docker build -t lissy93/dashy .` to build, and then use docker start to run the project, e.g: `docker run -it -p 8080:80 lissy93/dashy` (see the [deploying docs](https://github.com/Lissy93/dashy/blob/master/docs/deployment#deploy-with-docker) for more info)
---
## Auth Validation Error: "should be object"
In V 1.6.5 an update was made that in the future will become a breaking change. You will need to update you config to reflect this before V 2.0.0 is released. In the meantime, your previous config will continue to function normally, but you will see a validation warning. The change means that the structure of the `appConfig.auth` object is now an object, which has a `users` property.
For more info, see [this announcement](https://github.com/Lissy93/dashy/discussions/177).
You can fix this by replacing:
```yaml
auth:
- user: xxx
hash: xxx
```
with
```yaml
auth:
users:
- user: xxx
hash: xxx
```
---
## DockerHub `toomanyrequests`
This situation relates to error messages similar to one of the following, returned when pulling, updating or running the Docker container from Docker Hub.
```
Continuing execution. Pulling image lissy93/dashy:release-1.6.0
error pulling image configuration: toomanyrequests
```
or
```
You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
```
When DockerHub returns one of these errors, or a `429` status, that means you've hit your rate limit. This was [introduced](https://www.docker.com/blog/scaling-docker-to-serve-millions-more-developers-network-egress/) last year, and prevents unauthenticated or free users from running docker pull more than 100 times per 6 hours.
You can [check your rate limit status](https://www.docker.com/blog/checking-your-current-docker-pull-rate-limits-and-status/) by looking for the `ratelimit-remaining` header in any DockerHub responses.
#### Solution 1 - Use an alternate container registry
- Dashy is also availible through GHCR, which at present does not have any hard limits. Just use `docker pull ghcr.io/lissy93/dashy:latest` to fetch the image
- You can also build the image from source, by cloning the repo, and running `docker build -t dashy .` or use the pre-made docker compose
#### Solution 2 - Increase your rate limits
- Logging in to DockerHub will increase your rate limit from 100 requests to 200 requests per 6 hour period
- Upgrading to a Pro for $5/month will increase your image requests to 5,000 per day, and any plans above have no rate limits
- Since rate limits are counted based on your IP address, proxying your requests, or using a VPN may work
---
## Config Validation Errors
The configuration file is validated against [Dashy's Schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.json) using AJV.
First, check that your syntax is valid, using [YAML Validator](https://codebeautify.org/yaml-validator/) or [JSON Validator](https://codebeautify.org/jsonvalidator). If the issue persists, then take a look at the [schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.json), and verify that the field you are trying to add/ modify matches the required format. You can also use [this tool](https://www.jsonschemavalidator.net/s/JFUj7X9J) to validate your JSON config against the schema, or run `yarn validate-config`.
If you're trying to use a recently released feature, and are getting a warning, this is likely because you've not yet updated the the current latest version of Dashy.
If the issue still persists, you should raise an issue.
---
## Node Sass does not yet support your current environment
Caused by node-sass's binaries being built for a for a different architecture
To fix this, just run: `yarn rebuild node-sass`
---
## Error: Cannot find module './_baseValues'
Clearing the cache should fix this: `yarn cache clean`
If the issue persists, remove (`rm -rf node_modules\ yarn.lock`) and reinstall (`yarn`) node_modules
---
## Invalid Host Header while running through ngrok
Just add the [-host-header](https://ngrok.com/docs#http-host-header) flag, e.g. `ngrok http 8080 -host-header="localhost:8080"`
---
## Warnings in the Console during deploy
Please acknowledge the difference between errors and warnings before raising an issue about messages in the console. It's not unusual to see warnings about a new version of a certain package being available, an asset bundle bing oversized or a service worker not yet having a cache. These shouldn't have any impact on the running application, so please don't raise issues about these unless it directly relates to a bug or issue you're experiencing. Errors on the other hand should not appear in the console, and they are worth looking into further.

View File

@ -1,124 +0,0 @@
const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
/* External URLs */
const externalUrl = {
editUrl: 'https://github.com/Lissy93/dashy/edit/gh-pages/docs/',
licenseUrl: 'https://github.com/Lissy93/dashy/blob/master/LICENSE',
aliciaUrl: 'https://aliciasykes.com',
dashyUrl: 'https://dashy.to',
};
const footerText = `<a href="${externalUrl.dashyUrl}">Dashy</a> - The Self-Hosted Dashboard for your Homelab`
+ `<br />License under <a href="${externalUrl.licenseUrl}">MIT</a>. `
+ `Copyright © ${new Date().getFullYear()} <a href="${externalUrl.aliciaUrl}">Alicia Sykes</a>`;
/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
title: 'Dashy',
tagline: 'The Ultimate Homepage for your Homelab',
url: externalUrl.dashyUrl,
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'lissy93', // Usually your GitHub org/user name.
projectName: 'dashy', // Usually your repo name.
plugins: ['docusaurus-plugin-sass'],
themeConfig: {
navbar: {
title: 'Dashy',
logo: {
alt: 'Dashy Logo',
src: 'img/dashy.png',
},
items: [
],
},
footer: {
style: 'dark',
links: [
{
title: 'Intro',
items: [
{ label: 'GitHub', to: 'https://github.com/lissy93/dashy' },
{ label: 'Live Demo', to: 'https://demo.dashy.to' },
{ label: 'Quick Start', to: '/docs/quick-start' },
{ label: 'Documentation', to: '/docs' },
],
},
{
title: 'Setup Guide',
items: [
{ label: 'Deploying', to: '/docs/deployment' },
{ label: 'Configuring', to: '/docs/configuring' },
{ label: 'Management', to: '/docs/management' },
{ label: 'Troubleshooting', to: '/docs/troubleshooting' },
],
},
{
title: 'Feature Docs Pt 1',
items: [
{ label: 'Authentication', to: '/docs/authentication' },
{ label: 'Alternate Views', to: '/docs/alternate-views' },
{ label: 'Backup & Restore', to: '/docs/backup-restore' },
{ label: 'Icons', to: '/docs/icons' },
],
},
{
title: 'Feature Docs Pt 2',
items: [
{ label: 'Language Switching', to: '/docs/multi-language-support' },
{ label: 'Status Indicators', to: '/docs/status-indicators' },
{ label: 'Searching & Shortcuts', to: '/docs/searching' },
{ label: 'Theming', to: '/docs/theming' },
],
},
{
title: 'Community',
items: [
{ label: 'Developing', to: '/docs/developing' },
{ label: 'Development Guides', to: '/docs/development-guides' },
{ label: 'Contributing', to: '/docs/contributing' },
{ label: 'Showcase', to: '/docs/showcase' },
{ label: 'Credits', to: '/docs/credits' },
],
},
{
title: 'Misc',
items: [
{ label: 'Privacy & Security', to: '/docs/privacy' },
{ label: 'License', to: '/docs/license' },
{ label: 'Legal', to: 'https://github.com/Lissy93/dashy/blob/master/.github/LEGAL.md' },
{ label: 'Code of Conduct', to: '/docs/code-of-conduct' },
{ label: 'Changelog', to: '/docs/changelog' },
],
},
],
copyright: footerText,
},
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
},
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: externalUrl.editUrl,
},
theme: {
customCss: [
require.resolve('./src/styles/Colors.scss'),
require.resolve('./src/styles/Typography.scss'),
require.resolve('./src/styles/custom.scss'),
]
},
},
],
],
};

View File

@ -1,42 +0,0 @@
{
"name": "dashy",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.0.0-beta.2",
"@docusaurus/preset-classic": "2.0.0-beta.2",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",
"docusaurus-plugin-sass": "^0.2.1",
"file-loader": "^6.2.0",
"prism-react-renderer": "^1.2.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"sass": "^1.35.1",
"url-loader": "^4.1.1"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@ -1,43 +0,0 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
module.exports = {
// tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
dashySidebar: [
{
type: 'category',
label: 'Running Dashy',
items: ['quick-start', 'deployment', 'configuring', 'management', 'troubleshooting'],
},
{
type: 'category',
label: 'Community',
items: ['showcase', 'contributing', 'developing', 'development-guides'],
},
{
type: 'category',
label: 'Feature Docs',
items: [
'icons', 'theming', 'status-indicators',
'authentication', 'searching', 'alternate-views',
'multi-language-support', 'backup-restore',
],
},
{
type: 'category',
label: 'Misc',
items: ['privacy', 'changelog', 'license', 'code-of-conduct'],
},
],
};

View File

@ -1,12 +0,0 @@
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import './../styles/Button.scss';
export default function Button({ children, to, color }) {
return (
<Link to={to} className={clsx('button', color && 'color-btn', `btn-${color}`)}>
{children}
</Link>
);
}

View File

@ -1,56 +0,0 @@
import React, { useState } from 'react'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from '../styles/Header.module.scss';
import Button from '../components/Button';
// Icons
import IconBannerDemo from '../../static/icons/banner_demo.svg';
import IconBannerGetStarted from '../../static/icons/banner_get-started.svg';
import IconBannerSource from '../../static/icons/banner_source.svg';
import IconBannerDocs from '../../static/icons/banner_docs.svg';
import IconDownArrow from '../../static/icons/interface_down.svg';
export default function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
const [showMore, setShowMore] = useState(false);
return (
<header className={styles.heroBanner}>
<h1 className={styles.heroTitle}>{siteConfig.title}</h1>
<h3 className={styles.heroSubTitle}>{siteConfig.tagline}</h3>
<div className={styles.buttons}>
<Button to="/docs/quick-start" color="pink"><IconBannerGetStarted />Get Started</Button>
<Button to="/docs" color="blue"><IconBannerDemo />Try it Out</Button>
<Button to="https://github.com/Lissy93/dashy" color="green"><IconBannerSource />Source Code</Button>
<Button to="/docs" color="yellow"><IconBannerDocs />Documentation</Button>
</div>
<div className={styles.dashyDescription}>
Dashy is an open source, highly customizable, easy to use, privacy-respecting dashboard app.
{showMore && (
<p className={styles.dashyDescription}>
It's packed full of useful features, to help you build your perfect dashboard.
Including status checks, keyboard shortcuts, auto-fetched favicon icons and
font-awesome support, built-in authentication, tons of themes, a UI config
editor, many display layouts plus loads more.
All the code is free and open source, and everything is thoroughly documented,
you can get support with any questions on GitHub.
</p>
)}
<span className={styles.keepReading} onClick={() => setShowMore(!showMore)}>
{!showMore ? 'Keep Reading...' : 'Show Less'}
</span>
</div>
{(!showMore && document.body.scrollTop === 0) &&
<a href="#go-down" className={styles.scrollDown} id="go-down">
<IconDownArrow className={styles.scrollDownIcon} />
<span className={styles.scrollDownText}>Feature List</span>
<IconDownArrow className={styles.scrollDownIcon} />
</a>
}
<a href="https://github.com/lissy93/dashy">
<img className={styles.starButton}
src="https://img.shields.io/github/stars/Lissy93/Dashy?label=Dashy%20on%20GitHub&logo=github&style=social"
/>
</a>
</header>
);
}

View File

@ -1,206 +0,0 @@
import React from 'react';
import './../styles/HomePageFeatures.scss';
import Button from '../components/Button';
import getColor from '../utils/ui-helpers';
import IconAuth from '../../static/icons/features_authentication.svg';
import IconCloudSync from '../../static/icons/features_cloud-sync.svg';
import IconDeploy from '../../static/icons/features_depoloyment.svg';
import IconIconography from '../../static/icons/features_icons.svg';
import IconLayout from '../../static/icons/features_layout-customization.svg';
import IconOpeningMethods from '../../static/icons/features_opening-methods.svg';
import IconShortcuts from '../../static/icons/features_shortcuts.svg';
import IconStatusIndicators from '../../static/icons/features_status-indicators.svg';
import IconThemes from '../../static/icons/features_themes.svg';
import IconUiConfig from '../../static/icons/features_ui-configuration.svg';
import IconLaunching from '../../static/icons/features_launching.svg';
import IconLanguage from '../../static/icons/features_language.svg';
const FeatureList = [
{
title: 'Theming',
description: (
<>
With tons of built-in themes to choose form, plus a UI color palette editor,
you can have a unique looking dashboard in no time. There is also support for
custom CSS, and since all properties use CSS variables, it is easy to override.
</>
),
link: '/docs/theming',
icon: (<IconThemes />),
demo: '../../static/img/homepage-assets/theme-slideshow.gif',
},
{
title: 'Icons',
description: (
<>
Dashy can auto-fetch icons from the favicon of each of your apps/ services.
There is also native support for Font Awesome, Material Design Icons, emoji
icons and of course normal images.
</>
),
link: '/docs/icons',
icon: (<IconIconography />),
},
{
title: 'Status Indicators',
description: (
<>
Get an instant overview of the health of each of your apps with status indicators.
Once enabled, a small dot next to each app will show weather it is up and online,
with more info like response time visible on hover.
</>
),
link: '/docs/status-indicators',
icon: (<IconStatusIndicators />),
demo: '../../static/img/homepage-assets/status-check-demo.gif',
},
{
title: 'Authentication',
description: (
<>
Need to protect your dashboard, the simple auth feature is super quick to enable,
and has support for multiple users with granular controls. Dashy also has built-in
support for Keycloak and other SSO providers.
</>
),
link: '/docs/authentication',
icon: (<IconAuth />),
},
{
title: 'Alternate Views',
description: (
<>
As well as the default home, there is also a minimal view, which makes a great
fast-loading browser startpage. Plus a workspace view useful for working on
multiple apps at once, all without having to leave your dashboard.
</>
),
link: '/docs/alternate-views',
icon: (<IconOpeningMethods />),
demo: '../../static/img/homepage-assets/workspace-demo.gif',
},
{
title: 'Launching Methods',
description: (
<>
Choose how to launch each of your apps by default, or right click for all options.
Apps can be opened in a new tab, the same tab, a quick pop-up modal or in the
workspace view.
</>
),
link: '/docs/alternate-views',
icon: (<IconLaunching />),
},
{
title: 'Search & Shortcuts',
description: (
<>
To search, just start typing, results will be filtered instantly. Use the
arrow keys or tab to navigate through results, and press enter to launch.
You can also create custom shortcuts for frequently used apps, or add
custom tags for easier searching. Dashy can also be used to search the web
using your favorite search engine.
</>
),
link: '/docs/searching',
icon: (<IconShortcuts />),
demo: '../../static/img/homepage-assets/searching-demo.gif',
},
{
title: 'Cloud Backup & Sync',
description: (
<>
There is an optional, end-to-end encrypted, free backup cloud service.
This enables you to have your config backed up off-site, and to sync
data between multiple instances easily.
</>
),
link: '/docs/backup-restore',
icon: (<IconCloudSync />),
},
{
title: 'Configuration',
description: (
<>
Dashy's config is specified in a simple YAML file. But you can also configure
the directly through the UI, and have changes written to, and backed up on disk.
Real-time validation and hints are in place to help you.
</>
),
link: '/docs/configuring',
icon: (<IconUiConfig />),
demo: '../../static/img/homepage-assets/config-editor-demo.gif',
},
{
title: 'Multi-Language Support',
description: (
<>
Dashy's UI has been translated into several languages by several amazing contributors.
Currently English, German, French, Dutch and Slovenian are supported.
Your language should be applied automatically, or you can change it in the config menu.
</>
),
link: '/docs/multi-language-support',
icon: (<IconLanguage />),
},
{
title: 'Easy Deployment',
description: (
<>
Although Dashy can be easily run on bare metal, the quickest method of getting started is with Docker.
Just run `docker run -p 8080:80 lissy93/dashy` to pull, build and and run Dashy.
</>
),
link: '/docs/quick-start',
icon: (<IconDeploy />),
},
{
title: 'Customizable Layouts',
description: (
<>
Structure your dashboard to fit your use case. From the UI, you can choose between
different layouts, item sizes, show/ hide components, switch themes plus more.
You can customize pretty much every area of your dashboard. There are config
options for custom header, footer, nav bar links, title etc. You can also
choose to hide any elements you don't need.
</>
),
link: '/docs/',
icon: (<IconLayout />),
},
];
function Feature({ title, description, icon, demo, index, link }) {
const side = index % 2 == 0 ? 'left' : 'right';
const color = getColor(index)
return (
<div className={`feature align-${side} color-${color}`}>
<div className="feature-half text">
<div className="feature-title">{icon}<h3>{title}</h3></div>
{description}
<div className="read-the-docs">
<small>Learn more in the Docs</small>
<Button to={link} color={color}>{icon} Docs</Button>
</div>
</div>
<div className="feature-half assets">
{demo
? <img className="demo" src={demo} />
: <span className="not-demo">Screenshot Coming Soon</span>
}
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className="home-page-features-wrapper" id="features-wrap">
{FeatureList.map((props, index) => (
<Feature key={index} index={index} {...props} />
))}
</section>
);
}

View File

@ -1,256 +0,0 @@
import React from 'react';
import Layout from '@theme/Layout';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Button from '../components/Button';
import './docs.scss';
import getColor from '../utils/ui-helpers';
import IconCloudSync from '../../static/icons/features_cloud-sync.svg';
import IconDeploy from '../../static/icons/features_depoloyment.svg';
// import IconIconography from '../../static/icons/features_icons.svg';
// import IconLayout from '../../static/icons/features_layout-customization.svg';
// import IconOpeningMethods from '../../static/icons/features_opening-methods.svg';
// import IconShortcuts from '../../static/icons/features_shortcuts.svg';
// import IconStatusIndicators from '../../static/icons/features_status-indicators.svg';
// import IconThemes from '../../static/icons/features_themes.svg';
import IconUiConfig from '../../static/icons/features_ui-configuration.svg';
import IconTroubleshooting from '../../static/icons/docs_troubleshooting.svg';
import IconManagement from '../../static/icons/docs_managment.svg';
import IconDeveloping from '../../static/icons/docs_developing.svg';
import IconDevGuides from '../../static/icons/docs_guides.svg';
import IconContributing from '../../static/icons/docs_contributing.svg';
import IconShowcase from '../../static/icons/docs_showcase.svg';
import IconCredits from '../../static/icons/docs_credits.svg';
import IconAuth from '../../static/icons/docs_authentication.svg';
// import IconCloudSync from '../../static/icons/docs_cloud-sync.svg';
import IconIconography from '../../static/icons/docs_icons.svg';
import IconInternationalization from '../../static/icons/docs_internationalisation.svg';
import IconStatusIndicators from '../../static/icons/docs_status-indicators.svg';
import IconTheming from '../../static/icons/docs_theming.svg';
import IconQuickStart from '../../static/icons/docs_quick-start.svg';
import IconAlternateViews from '../../static/icons/features_launching.svg';
import IconShortcuts from '../../static/icons/features_shortcuts.svg';
import IconSecurity from '../../static/icons/docs_security.svg';
import IconLegal from '../../static/icons/docs_legal.svg';
import IconConduct from '../../static/icons/docs_conduct.svg';
import IconChangelog from '../../static/icons/docs_changelog.svg';
const DocsLinks = [
{
title: 'Deployment',
description: 'Getting Dashy up and running',
link: '/docs/deployment',
icon: (<IconDeploy />),
},
{
title: 'Configuring',
description: 'All Config Options',
link: '/docs/configuring',
icon: (<IconUiConfig />),
},
{
title: 'Management',
description: 'Updating, security, web server configuration, etc',
link: '/docs/management',
icon: (<IconManagement />),
},
{
title: 'Troubleshooting',
description: 'Solutions to Common Issues',
link: '/docs/troubleshooting',
icon: (<IconTroubleshooting />),
},
];
const DocsSections = [
{
section: 'Running Dashy',
items: [
{
title: 'Quick-Start',
description: 'TLDR Guide on running Dashy',
link: '/docs/quick-start',
icon: (<IconQuickStart />),
},
{
title: 'Deployment',
description: 'Deploying Dashy to any server',
link: '/docs/deployment',
icon: (<IconDeploy />),
},
{
title: 'Configuring',
description: 'All Config Options',
link: '/docs/configuring',
icon: (<IconUiConfig />),
},
{
title: 'Management',
description: 'Updating, security, web server configuration, etc',
link: '/docs/management',
icon: (<IconManagement />),
},
{
title: 'Troubleshooting',
description: 'Solutions to Common Issues',
link: '/docs/troubleshooting',
icon: (<IconTroubleshooting />),
},
]
},
{
section: 'Community',
items: [
{
title: 'Developing',
description: 'Dashy workflow, and running locally',
link: '/docs/developing',
icon: (<IconDeveloping />),
},
{
title: 'Dev Guides',
description: 'Common development tasks',
link: '/docs/development-guides',
icon: (<IconDevGuides />),
},
{
title: 'Contributing',
description: 'How you can help support Dashy\'s development',
link: '/docs/contributing',
icon: (<IconContributing />),
},
{
title: 'Showcase',
description: 'See how others are using Dashy, and share your dashboard',
link: '/docs/showcase',
icon: (<IconShowcase />),
},
{
title: 'Credits',
description: 'List of people and projects that have made Dashy possible',
link: '/docs/credits',
icon: (<IconCredits />),
},
]
},
{
section: 'Feature Docs',
items: [
{
title: 'Authentication',
description: 'Configure login and user control',
link: '/docs/authentication',
icon: (<IconAuth />),
},
{
title: 'Alternate Views',
description: 'Startpage mode, Workspace and opening methods',
link: '/docs/alternate-views',
icon: (<IconAlternateViews />),
},
{
title: 'Backup & Restore',
description: 'Cloud Sync, usage and background',
link: '/docs/backup-restore',
icon: (<IconCloudSync />),
},
{
title: 'Icons',
description: 'Available icon types for sections and items',
link: '/docs/icons',
icon: (<IconIconography />),
},
{
title: 'Language Switching',
description: 'Changing language, and adding new locales',
link: '/docs/multi-language-support',
icon: (<IconInternationalization />),
},
{
title: 'Status Indicators',
description: 'Monitoring uptime of your services with Dashy',
link: '/docs/status-indicators',
icon: (<IconStatusIndicators />),
},
{
title: 'Search & Shortcuts',
description: 'Filtering, web search and custom hotkeys',
link: '/docs/searching',
icon: (<IconShortcuts />),
},
{
title: 'Theming',
description: 'Guide to customizing the look and feel of Dashy',
link: '/docs/theming',
icon: (<IconTheming />),
},
]
},
{
section: 'Misc',
items: [
{
title: 'Privacy & Security',
description: 'Configure login and user control',
link: '/docs/privacy',
icon: (<IconSecurity />),
},
{
title: 'License',
description: 'Configure login and user control',
link: '/docs/license',
icon: (<IconLegal />),
},
{
title: 'Code of Conduct',
description: 'Configure login and user control',
link: '/docs/code-of-conduct',
icon: (<IconConduct />),
},
{
title: 'Changelog',
description: 'Configure login and user control',
link: '/docs/changelog',
icon: (<IconChangelog />),
},
]
}
];
function DocsLink({ title, description, icon, link, index }) {
const color = getColor(index);
return (
<Button to={link} className="docs-link" color={color}>
<div className="row1">
{icon}
<p className="name">{title}</p>
</div>
<span className="description">{description}</span>
</Button>
);
}
export default function Docs() {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={siteConfig.title}
description="Documentation | Dashy, a self-hosted dashboard for your homelab">
<main className="docs">
<h1 className="docs-title">Dashy Docs</h1>
<div className="docs-contents">
{DocsSections.map((DocsLinks, indexOuter) => (
<div key={indexOuter}>
<h3 className="section-title">{indexOuter + 1}. {DocsLinks.section}</h3>
<div className="docs-links-section">
{DocsLinks.items.map((props, index) => (<DocsLink key={indexOuter + index} index={indexOuter + index} {...props} />))}
</div>
</div>
)
)}
</div>
</main>
</Layout>
);
}

View File

@ -1,54 +0,0 @@
main.docs {
max-width: 1250px;
margin: 1rem auto;
padding: 1rem;
background: var(--hero-background);
box-shadow: var(--feature-img-shadow);
h1.docs-title {
margin: 0;
font-size: 5rem;
}
div.row1 {
display: flex;
flex-direction: row;
}
div.docs-links-section {
display: flex;
flex-wrap: wrap;
}
div.docs-contents {
color: var(--text-color);
display: flex;
justify-content: space-around;
flex-direction: column;
h3.section-title {
margin: 1rem 0.5rem 0.5rem 0.5rem;
}
a {
display: flex;
flex-direction: column;
width: calc(33% - 1.5rem);
min-height: 5rem;
padding: 0.25rem 0.5rem;
margin: 0.5rem 0.75rem;
p.name {
margin: 0;
text-align: left;
font-size: 1.4rem;
}
span.description {
text-align: left;
font-size: 1rem;
white-space: pre-wrap;
}
@media (max-width: 500px) {
width: 100%;
}
}
}
}

View File

@ -1,22 +0,0 @@
import React from 'react';
import Layout from '@theme/Layout';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from './index.module.scss';
import HomePageHeader from '../components/HomePageHeader';
import HomePageFeatures from '../components/HomepageFeatures';
export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={siteConfig.title}
description="Description will go into a meta tag in <head />">
<HomePageHeader />
<HomePageFeatures />
<main>
</main>
</Layout>
);
}

View File

@ -1,46 +0,0 @@
/* stylelint-disable docusaurus/copyright-header */
html {
&[data-theme='dark'] {
--heading-shadow: -5px 4px 0px #000000;
--sub-heading-shadow: -3px 3px 1px #000000;
}
&[data-theme='light'] {
--heading-shadow: -2px 3px 2px #a2a1a1;
--sub-heading-shadow: -1px 1px 1px #a2a1a1;
}
}
header.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
background: var(--hero-background);
h1.heroTitle {
font-size: 6rem;
font-family: 'Racing Sans One', mono;
text-shadow: var(--heading-shadow);
}
h3.heroSubTitle {
text-shadow: var(--sub-heading-shadow);
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
@media screen and (max-width: 966px) {
flex-direction: column;
}
}
@media screen and (max-width: 966px) {
.heroBanner {
padding: 2rem;
}
}

View File

@ -1,7 +0,0 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.

View File

@ -1,72 +0,0 @@
.button-link-wrapper:hover {
text-decoration: none;
}
.button {
border-radius: 4px;
cursor: pointer;
display: inline-block;
font-weight: 600;
position: relative;
transition: none;
border: none;
min-width: 12rem;
font-weight: bold;
font-size: 1.3rem;
padding: 0.75rem 1rem;
margin: 0.5rem;
color: var(--black);
display: flex;
svg {
width: 1.8rem;
margin-right: 0.5rem;
}
&.color-btn:hover {
color: #000000b3;
top: 2px;
}
&.color-btn:active {
color: #00000080;
top: 4px;
box-shadow: none !important;
}
&.color-btn.btn-pink {
background: #db78fc;
box-shadow: 0 4px #b83ddd;
&:hover {
box-shadow: 0 2px #b83ddd;
}
}
&.color-btn.btn-purple {
background: #9083ed;
box-shadow: 0 4px #6b3cd6;
&:hover {
box-shadow: 0 2px #6b3cd6;
}
}
&.color-btn.btn-blue {
background: #5c85f7;
box-shadow: 0 4px #3d48dd;
&:hover {
box-shadow: 0 2px #3d48dd;
}
}
&.color-btn.btn-green {
background: #41ef90;
box-shadow: 0 4px #1e9554;
&:hover {
box-shadow: 0 2px #1e9554;
}
}
&.color-btn.btn-yellow {
background: #dcff5a;
box-shadow: 0 4px #ceb73f;
&:hover {
box-shadow: 0 2px #ceb73f;
}
}
}

View File

@ -1,43 +0,0 @@
/* Global Color Palette */
:root {
/* Greyscale */
--bright-white: #ffffff;
--white: #f7f7f7;
--pale-grey: #e9e9e8;
--mid-grey: #a9a9a9;
--dark-grey: ##18191a;
--black: #121212;
--pitch-black: #000000;
/* Action Colors */
--info: #35c9fa;
--success: #88ff88;
--warning: #ece715;
--danger: #f80363;
}
/* Themed Color Palette */
html { /* Light Theme */
--primary: #54bff7;
--background: var(--white);
--text-color: var(--black);
--hero-background: var(--bright-white);
--kinda-transparent: #ffffffd9;
--hyperlink: #ff62ce;
--feature-img-shadow: 4px 4px 6px #a9a9a980, -2px -2px 4px rgb(0 0 0 / 40%);
--footer-color: var(--white);
--footer-text-color: var(--black);
}
html[data-theme='dark'] { /* Dark Theme */
--primary: #db78fc;
--background: var(--dark-grey);
--text-color: var(--white);
--hero-background: var(--black);
--kinda-transparent: #000000d9;
--hyperlink: var(--primary);
--feature-img-shadow: 4px 4px 6px #00000080, -2px -2px 4px rgb(0 0 0 / 40%);
--footer-color: var(--black);
--footer-text-color: var(--white);
}

View File

@ -1,82 +0,0 @@
html {
&[data-theme='dark'] {
--heading-shadow: -5px 4px 0px #000000;
--sub-heading-shadow: -3px 3px 1px #000000;
}
&[data-theme='light'] {
--heading-shadow: -2px 3px 2px #a2a1a1;
--sub-heading-shadow: -1px 1px 1px #a2a1a1;
}
}
header.heroBanner {
padding: 4rem 1rem;
text-align: center;
position: relative;
overflow: hidden;
background: var(--hero-background);
min-height: calc(100vh - 4rem);
h1.heroTitle {
font-size: 8rem;
font-family: 'Racing Sans One', cursive;
text-shadow: var(--heading-shadow);
}
h3.heroSubTitle {
text-shadow: var(--sub-heading-shadow);
}
img.starButton {
position: absolute;
width: 12rem;
top: 1rem;
right: 1rem;
opacity: 0.85;
&:hover {
opacity: 1;
}
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
margin: 1.5rem;
@media screen and (max-width: 966px) {
flex-direction: column;
}
}
.dashyDescription {
max-width: 680px;
margin: 1rem auto;
text-align: left;
font-size: 1.2rem;
}
.keepReading {
font-size: 1.2rem;
margin-left: 0.5rem;
cursor: pointer;
text-decoration: underline;
}
.scrollDown {
display: flex;
width: fit-content;
cursor: pointer;
margin: 2rem auto;
position: absolute;
bottom: 2rem;
left: 42%;
@media (max-width: 966px) {
display: none;
}
}
.scrollDownText {
margin: 0 1rem;
font-size: 1.2rem;
font-weight: bold;
}
.scrollDownIcon {
width: 2rem;
}

View File

@ -1,87 +0,0 @@
.color-pink { --feature-color: #db78fc; }
.color-blue { --feature-color: #5c85f7; }
.color-green { --feature-color: #41ef90; }
.color-yellow { --feature-color: #dcff5a; }
.color-white { --feature-color: white; }
html[data-theme='light'] { /* Dark Theme */
.color-pink { --feature-color: #b83ddd; }
.color-blue { --feature-color: #6b3cd6; }
.color-green { --feature-color: #1e9554; }
.color-yellow { --feature-color: #ceb73f; }
.color-white { --feature-color: #000; }
}
.home-page-features-wrapper {
display: flex;
flex-direction: column;
font-size: 1.2rem;
.feature {
display: flex;
justify-content: center;
align-items: center;
padding: 0.5rem;
margin: 0;
&.align-left {
flex-direction: row;
background: var(--background);
box-shadow: 0 1px 4px #000000;
}
&.align-right {
flex-direction: row-reverse;
background: var(--hero-background);
box-shadow: 0 -1px 4px #000000b3;
}
.feature-half {
width: 40%;
padding: 0.25rem;
margin: 1rem;
&.assets {
background: var(--feature-color);
display: flex;
align-items: center;
justify-content: center;
margin: 0.5rem;
height: fit-content;
border-radius: 8px;
box-shadow: var(--feature-img-shadow);
img.demo, span.not-demo {
background: var(--kinda-transparent);
width: 100%;
max-height: 36rem;
min-height: 12rem;
height: 100%;
object-fit: contain;
border-radius: 8px;
box-shadow: var(--feature-img-shadow);
}
span.not-demo {
display: flex;
align-items: center;
justify-content: center;
}
}
}
.feature-title {
display: flex;
align-items: flex-end;
margin: 1rem 0;
color: var(--feature-color);
svg {
margin-right: 0.5rem;
width: 2rem;
}
h3 {
margin: 0;
}
}
div.read-the-docs {
float: right;
a.button-link-wrapper {
margin: 0 1rem 1rem;
}
small {
opacity: 0.75;
margin: 0 0.5rem;
}
}
}
}

View File

@ -1,24 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Racing+Sans+One&family=Raleway:wght@200&family=Roboto+Mono:wght@500&display=swap');
h1 {
font-size: 4rem;
font-family: 'Racing Sans One', mono;
}
h2 {
font-size: 3rem;
font-family: 'Roboto Mono', monospace;
}
h3 {
font-size: 2rem;
font-family: 'Roboto Mono', monospace;
}
h4, h5, button {
font-size: 1.2rem;
font-family: 'Roboto Mono', monospace;
}
body, section, p, span, a, div, ul li {
font-size: 1.2rem;
font-family: 'Raleway', sans-serif;
}

View File

@ -1,151 +0,0 @@
/* stylelint-disable docusaurus/copyright-header */
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: var(--background);
--ifm-color-primary-dark: rgb(33, 175, 144);
--ifm-color-primary-darker: rgb(31, 165, 136);
--ifm-color-primary-darkest: rgb(26, 136, 112);
--ifm-color-primary-light: rgb(70, 203, 174);
--ifm-color-primary-lighter: rgb(102, 212, 189);
--ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
--ifm-navbar-background-color: var(--hero-background);
--ifm-navbar-link-color: var(--text-color);
}
.hero {
--ifm-hero-background-color: var(--hero-background);
--ifm-hero-text-color: var(--text-color);
}
.footer {
box-shadow: var(--feature-img-shadow);
--ifm-footer-background-color: var(--footer-color);
--ifm-footer-color: var(--footer-text-color);
--ifm-footer-link-color: var(--footer-text-color);
--ifm-footer-title-color: var(--footer-text-color);
--ifm-footer-link-hover-color: var(--primary);
--ifm-link-color: var(--footer-text-color);
--ifm-link-hover-color: var(--primary);
.footer__link-item {
font-size: 1rem;
}
.footer__copyright, .footer__copyright a {
font-size: 0.9rem;
font-weight: bold;
opacity: 0.9;
font-family: 'Roboto Mono', monospace;
}
}
.docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.1);
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
nav.navbar {
box-shadow: var(--feature-img-shadow);
a.navbar__brand b {
font-weight: bold;
font-size: 1.5rem;
}
}
body {
background: var(--background);
}
p a, li a {
color: var(--hyperlink);
&:hover {
color: var(--hyperlink);
text-decoration: underline;
}
}
h1, h2, h3, h4, h5 {
cursor: default;
}
/* Markdown Docs content */
article div.markdown {
--ifm-h1-font-size: 3.0rem;
--ifm-h2-font-size: 2.5rem;
--ifm-h3-font-size: 1.4rem;
p, a, ol, ul, li, code span {
font-size: 1rem;
}
h1 { font-size: var(--ifm-h1-font-size); }
h2 { font-size: var(--ifm-h2-font-size); }
h3 { font-size: var(--ifm-h3-font-size); }
p img {
border-radius: 4px;
}
table > tr > td > a > img {
border-radius: 6px;
}
}
/* Right-hand contents side-bar */
ul.table-of-contents li {
a {
font-size: 1rem;
&:hover, &:hover code {
color: var(--hyperlink);
}
&.table-of-contents__link--active, &.table-of-contents__link--active code {
color: var(--hyperlink);
font-weight: bold;
}
}
}
/* Left-hand page list side-bar */
ul.menu__list {
margin-bottom: 1rem;
li.menu__list-item {
a {
&.active {
color: var(--hyperlink);
font-weight: bold;
}
}
}
}
/* Code Blocks */
code span {
font-family: 'Roboto Mono', monospace;
font-size: 0.9rem !important;
}
html[data-theme='light'] {
main div.container.padding-top--md.padding-bottom--lg{
padding: 0 1rem !important;
div > div.col.docItemCol_node_modules-\@docusaurus-theme-classic-lib-next-theme-DocItem-styles-module {
padding: 1rem;
background: var(--bright-white);
border-right: 1px solid var(--ifm-toc-border-color);
ul li a {
font-weight: bold;
}
}
.table-of-contents__left-border {
border-left: none;
}
.pagination-nav__label {
color: var(--black);
}
}
}

View File

@ -1,18 +0,0 @@
/**
* Returns a color class name for elements relative to their position
* @param index The position of a given element
* @returns A color, relational to position
*/
const getColor = (index: number): string => {
const remainder = index % 4;
switch (remainder) {
case 0: return 'pink';
case 1: return 'blue';
case 2: return 'green';
case 3: return 'yellow';
default: return 'white';
}
};
export default getColor;

View File

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="browser" class="svg-inline--fa fa-browser fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM48 92c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V92zm416 334c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V168h416v258zm0-310c0 6.6-5.4 12-12 12H172c-6.6 0-12-5.4-12-12V92c0-6.6 5.4-12 12-12h280c6.6 0 12 5.4 12 12v24z"></path></svg>

Before

Width:  |  Height:  |  Size: 590 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="book-heart" class="svg-inline--fa fa-book-heart fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M448 384V16c0-8.8-7.2-16-16-16H80C35.8 0 0 35.8 0 80v352c0 44.2 35.8 80 80 80h352c8.8 0 16-7.2 16-16v-16c0-7.8-5.6-14.3-12.9-15.7-4.2-13-4.2-51.6 0-64.6 7.4-1.5 12.9-7.9 12.9-15.7zm-54 80H80c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h314c-2.7 17.3-2.7 46.7 0 64zm6-112H80c-11.4 0-22.2 2.4-32 6.7V80c0-17.7 14.3-32 32-32h320v304zm-184.5-67.5c4.7 4.6 12.3 4.6 17 0l72.6-71.3c21.1-20.7 19.8-55.1-3.7-74.2s-54.3-10.6-70 4.8l-7.4 7.3-7.4-7.3c-15.3-15.1-46.2-24.1-70-4.8-23.6 19.1-24.8 53.5-3.7 74.2l72.6 71.3z"></path></svg>

Before

Width:  |  Height:  |  Size: 744 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="sparkles" class="svg-inline--fa fa-sparkles fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M324.42 103.16L384 128l24.84 59.58a8 8 0 0 0 14.32 0L448 128l59.58-24.84a8 8 0 0 0 0-14.32L448 64 423.16 4.42a8 8 0 0 0-14.32 0L384 64l-59.58 24.84a8 8 0 0 0 0 14.32zm183.16 305.68L448 384l-24.84-59.58a8 8 0 0 0-14.32 0L384 384l-59.58 24.84a8 8 0 0 0 0 14.32L384 448l24.84 59.58a8 8 0 0 0 14.32 0L448 448l59.58-24.84a8 8 0 0 0 0-14.32zM384 256a24 24 0 0 0-13.28-21.47l-104.85-52.42-52.4-104.84c-8.13-16.25-34.81-16.25-42.94 0l-52.41 104.84-104.84 52.42a24 24 0 0 0 0 42.94l104.84 52.42 52.41 104.85a24 24 0 0 0 42.94 0l52.4-104.85 104.85-52.42A24 24 0 0 0 384 256zm-146.72 34.53a24 24 0 0 0-10.75 10.74L192 370.33l-34.53-69.06a24 24 0 0 0-10.75-10.74L77.66 256l69.06-34.53a24 24 0 0 0 10.75-10.73L192 141.67l34.53 69.07a24 24 0 0 0 10.75 10.73L306.34 256z"></path></svg>

Before

Width:  |  Height:  |  Size: 991 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="github-alt" class="svg-inline--fa fa-github-alt fa-w-15" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 512"><path fill="currentColor" d="M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="user-shield" class="svg-inline--fa fa-user-shield fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M622.3 271.1l-115.2-45c-4.1-1.6-12.6-3.7-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9 9.6 3.7 18 1.6 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8zM356.2 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 47.1 0 70.9-13.5 85.4-15.5-2.9-15.2-4.6-31-5.1-47.5-25.6 3.2-39.5 15-80.4 15-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h351.3c-15.5-13.7-30.2-29.7-43.1-48zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z"></path></svg>

Before

Width:  |  Height:  |  Size: 899 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="stream" class="svg-inline--fa fa-stream fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M16 128h416c8.84 0 16-7.16 16-16V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v32c0 8.84 7.16 16 16 16zm480 96H80c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-64 160H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z"></path></svg>

Before

Width:  |  Height:  |  Size: 552 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="cloud-upload-alt" class="svg-inline--fa fa-cloud-upload-alt fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M395.5 267.5l-99-99c-4.7-4.7-12.3-4.7-17 0l-99 99c-7.6 7.6-2.2 20.5 8.5 20.5h67v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-84h67c10.7 0 16.1-12.9 8.5-20.5zm148.2-67.4C539.7 142.1 491.4 96 432 96c-7.6 0-15.1.8-22.4 2.3C377.7 58.3 328.1 32 272 32c-84.6 0-155.5 59.7-172.3 139.8C39.9 196.1 0 254.4 0 320c0 88.4 71.6 160 160 160h336c79.5 0 144-64.5 144-144 0-61.8-39.2-115.8-96.3-135.9zM496 432H160c-61.9 0-112-50.1-112-112 0-56.4 41.7-103.1 96-110.9V208c0-70.7 57.3-128 128-128 53.5 0 99.3 32.8 118.4 79.4 11.2-9.6 25.7-15.4 41.6-15.4 35.3 0 64 28.7 64 64 0 11.8-3.2 22.9-8.8 32.4 2.9-.3 5.9-.4 8.8-.4 53 0 96 43 96 96s-43 96-96 96z"></path></svg>

Before

Width:  |  Height:  |  Size: 883 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="hand-sparkles" class="svg-inline--fa fa-hand-sparkles fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M471.38,467.5l-1-.43-1-.49a37.63,37.63,0,0,1-6.06-4.23,31.74,31.74,0,0,1-9.47,1.65H273.14a32.29,32.29,0,0,1-26.69-14.3L132.34,277.8c-18-25.71,20.7-54.1,39.3-27.5l37.81,54.4c4.5,6.5,14.59,3.21,14.59-4.61V104c0-31.8,48-31.7,48,0V248a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8V72c0-31.8,48-31.7,48,0V248a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8V104c0-31.8,48-31.7,48,0V248a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8V184c0-31.8,48-31.7,48,0v88.3a321.9,321.9,0,0,1-6.2,62.79L495.6,386.4l13.27-5.53,15.63-37.49.41-1,.47-.95c5.83-11.74,18-19.6,31-20.92A371.21,371.21,0,0,0,560,272.3V184A71.94,71.94,0,0,0,488,112c-2.7,0-5.4.2-8,.41V104a72.08,72.08,0,0,0-72-72,70.77,70.77,0,0,0-18.59,2.41,72,72,0,0,0-122.81,0A70.79,70.79,0,0,0,248,32a72.08,72.08,0,0,0-72,72v92.09c-10.5-3.68-38.09-10.18-65.29,8.91A72.13,72.13,0,0,0,93,305.3l113.5,171a79.81,79.81,0,0,0,66.6,35.7H453.75a79.85,79.85,0,0,0,57-24.3l-1.9-4.57ZM86,156.3l20.69-49.63h0l.09,0L156.3,86A7.29,7.29,0,0,0,160,80h0A7.28,7.28,0,0,0,156.3,74L106.73,53.37l-.07,0L86,3.7A6.65,6.65,0,0,0,74,3.7L53.34,53.33l-.05,0L3.7,74A7.28,7.28,0,0,0,0,80H0A7.29,7.29,0,0,0,3.7,86l49.57,20.67.07,0L74,156.3a6.65,6.65,0,0,0,11.92,0ZM307.58,288a4,4,0,0,0-7.15,0L288,317.79l-29.79,12.42a4,4,0,0,0,0,7.15L288,349.78l12.42,29.78a4,4,0,0,0,7.15,0L320,349.78l29.79-12.42a4,4,0,0,0,0-7.15L320,317.79ZM640,432A7.28,7.28,0,0,0,636.3,426l-49.57-20.67-.07,0L566,355.7a6.65,6.65,0,0,0-11.92,0l-20.7,49.63-.05,0L483.7,426A7.28,7.28,0,0,0,480,432h0A7.29,7.29,0,0,0,483.7,438l49.57,20.67.07,0L554,508.3a6.65,6.65,0,0,0,11.92,0l20.69-49.63h0l.09-.05L636.3,438A7.29,7.29,0,0,0,640,432h0Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="heart-circle" class="svg-inline--fa fa-heart-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M361.8 162.8c-38.3-32.8-89-17.8-113.8 7.8-24.8-25.6-75.5-40.6-113.8-7.8-42.4 36.2-36.1 95.2-6 126.3l98.7 102c13 13.4 32.5 10.2 42.4 0l98.7-102c29.9-31.1 36.2-90.1-6.2-126.3zm-27.7 92.7l-86.1 89-86.1-89.1c-13-13.5-16.2-39.7 2.7-55.9 14.1-12 36.1-9 49.3 4.7l34.1 35.4 34.1-35.4c13.2-13.7 35.3-16.7 49.3-4.7 18.9 16.2 15.8 42.5 2.7 56zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200z"></path></svg>

Before

Width:  |  Height:  |  Size: 728 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="trophy-alt" class="svg-inline--fa fa-trophy-alt fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M359.3 138.9l-43.4-6.3-19.4-39.3c-3.5-7-13.5-7.1-17 0l-19.4 39.3-43.4 6.3c-7.8 1.1-10.9 10.7-5.3 16.2l31.4 30.6-7.4 43.2c-1.3 7.7 6.8 13.7 13.8 10l38.8-20.4 38.8 20.4c6.9 3.6 15.1-2.2 13.8-10l-7.4-43.2 31.4-30.6c5.6-5.5 2.5-15.1-5.3-16.2zM448 64V16c0-8.8-7.2-16-16-16H144c-8.8 0-16 7.2-16 16v48H16C7.2 64 0 71.2 0 80v60.8C0 201.1 68.3 266 159.6 283.4c27.4 57.9 68.1 88.2 104.4 97.4V464h-64c-22.1 0-40 17.9-40 40 0 4.4 3.6 8 8 8h240c4.4 0 8-3.6 8-8 0-22.1-17.9-40-40-40h-64v-83.2c36.3-9.3 77-39.5 104.4-97.4C507.5 266.1 576 201.2 576 140.8V80c0-8.8-7.2-16-16-16H448zM48 140.8V112h80c0 39.2 2.1 76.2 12.3 116.8-55.1-18.9-92.3-58.9-92.3-88zM288 336c-53 0-112-78.4-112-216V48h224v72c0 140.5-60.8 216-112 216zm240-195.2c0 29.1-37.2 69.1-92.3 88C445.9 188.2 448 151.1 448 112h80v28.8z"></path></svg>

Before

Width:  |  Height:  |  Size: 1018 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="laptop-code" class="svg-inline--fa fa-laptop-code fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M624 352h-48V64c0-35.2-28.8-64-64-64H128C92.8 0 64 28.8 64 64v288H16c-8.8 0-16 7.2-16 16v48c0 52.8 43.2 96 96 96h448c52.8 0 96-43.2 96-96v-48c0-8.8-7.2-16-16-16zM112 64c0-8.67 7.33-16 16-16h384c8.67 0 16 7.33 16 16v288H112V64zm480 352c0 26.47-21.53 48-48 48H96c-26.47 0-48-21.53-48-48v-16h180.9c5.57 9.39 15.38 16 27.1 16h128c11.72 0 21.52-6.61 27.1-16H592v16zM277.66 261.65l11.31-11.31c6.25-6.25 6.25-16.38 0-22.63L253.25 192l35.71-35.72c6.25-6.25 6.25-16.38 0-22.63l-11.31-11.31c-6.25-6.25-16.38-6.25-22.63 0l-58.34 58.34c-6.25 6.25-6.25 16.38 0 22.63l58.34 58.34c6.25 6.25 16.39 6.25 22.64 0zm73.38-11.3l11.31 11.31c6.25 6.25 16.38 6.25 22.63 0l58.34-58.34c6.25-6.25 6.25-16.38 0-22.63l-58.34-58.34c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63L386.75 192l-35.71 35.72c-6.25 6.25-6.25 16.38 0 22.63z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="graduation-cap" class="svg-inline--fa fa-graduation-cap fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M606.72 147.91l-258-79.57c-18.81-5.78-38.62-5.78-57.44 0l-258 79.57C13.38 154.05 0 171.77 0 192.02s13.38 37.97 33.28 44.11l22.64 6.98c-2.46 5.19-4.4 10.62-5.7 16.31C39.53 264.6 32 275.33 32 288.01c0 10.78 5.68 19.85 13.86 25.65L20.33 428.53C18.11 438.52 25.71 448 35.95 448h56.11c10.24 0 17.84-9.48 15.62-19.47L82.14 313.66c8.17-5.8 13.86-14.87 13.86-25.65 0-10.6-5.49-19.54-13.43-25.36 1.13-3.55 2.96-6.67 4.85-9.83l54.87 16.92L128 384c0 35.34 85.96 64 192 64s192-28.65 192-64l-14.28-114.26 109-33.62c19.91-6.14 33.28-23.86 33.28-44.11s-13.38-37.96-33.28-44.1zM462.44 374.47c-59.7 34.2-225.9 33.78-284.87 0l11.3-90.36 102.42 31.59c11.15 3.43 32.24 7.77 57.44 0l102.42-31.59 11.29 90.36zM334.59 269.82c-9.44 2.91-19.75 2.91-29.19 0L154.62 223.3l168.31-31.56c8.69-1.62 14.41-9.98 12.78-18.67-1.62-8.72-10.09-14.36-18.66-12.76l-203.78 38.2c-6.64 1.24-12.8 3.54-18.71 6.27L53.19 192l252.22-77.79c9.44-2.91 19.75-2.91 29.19 0l252.22 77.82-252.23 77.79z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="icons" class="svg-inline--fa fa-icons fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M144 343.78a48 48 0 1 0 48 48 48 48 0 0 0-48-48zM101.74 213a37 37 0 0 0 52.36 0l78.56-78.44A79.06 79.06 0 0 0 227 17.49c-28.08-23.13-69.54-22.82-99-.86-29.45-22-71-22.3-99.05.89a79.11 79.11 0 0 0-5.77 117.08zM59.42 54.53A29.54 29.54 0 0 1 78.35 48 35.08 35.08 0 0 1 103 58.32l25 24.89 24.93-24.89c12.25-12.15 31.43-13.83 43.58-3.82a31.09 31.09 0 0 1 2.31 46.15l-70.85 70.71-70.87-70.69a31.13 31.13 0 0 1 2.32-46.14zm337.93 305.24l32.27-69.89a24 24 0 1 0-43.54-20.12l-63.7 138h109.27l-36.92 68.58A24 24 0 1 0 437 499.05l75-139.28zm-141.44-72h-27.42l-7.09-14.17a27.36 27.36 0 0 0-25.64-17.76H92.08a27.39 27.39 0 0 0-25.65 17.76l-7 14.21H32a32 32 0 0 0-32 32V480a32 32 0 0 0 32 32h223.91a32 32 0 0 0 32-32V319.79a32 32 0 0 0-32-31.98zm-16 176.23H48V335.79h41.22l13.21-26.73 2.57-5.26h77.83l2.69 5.4 13.24 26.59h41.13zm112-256V68.24L463.83 51v78.58a84 84 0 0 0-16-1.69c-35.34 0-64 21.47-64 48s28.64 48 64 48 64-21.48 64-48V32c0-17.9-13.54-32-29.64-32a28.08 28.08 0 0 0-4.26.33L329.39 23.17c-14.63 2.25-25.5 15.74-25.5 31.66V161.6a83.25 83.25 0 0 0-16-1.7c-35.33 0-64 21.55-64 48.13s28.64 48.13 64 48.13 63.98-21.55 63.98-48.16z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="globe" class="svg-inline--fa fa-globe fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm179.3 160h-67.2c-6.7-36.5-17.5-68.8-31.2-94.7 42.9 19 77.7 52.7 98.4 94.7zM248 56c18.6 0 48.6 41.2 63.2 112H184.8C199.4 97.2 229.4 56 248 56zM48 256c0-13.7 1.4-27.1 4-40h77.7c-1 13.1-1.7 26.3-1.7 40s.7 26.9 1.7 40H52c-2.6-12.9-4-26.3-4-40zm20.7 88h67.2c6.7 36.5 17.5 68.8 31.2 94.7-42.9-19-77.7-52.7-98.4-94.7zm67.2-176H68.7c20.7-42 55.5-75.7 98.4-94.7-13.7 25.9-24.5 58.2-31.2 94.7zM248 456c-18.6 0-48.6-41.2-63.2-112h126.5c-14.7 70.8-44.7 112-63.3 112zm70.1-160H177.9c-1.1-12.8-1.9-26-1.9-40s.8-27.2 1.9-40h140.3c1.1 12.8 1.9 26 1.9 40s-.9 27.2-2 40zm10.8 142.7c13.7-25.9 24.4-58.2 31.2-94.7h67.2c-20.7 42-55.5 75.7-98.4 94.7zM366.3 296c1-13.1 1.7-26.3 1.7-40s-.7-26.9-1.7-40H444c2.6 12.9 4 26.3 4 40s-1.4 27.1-4 40h-77.7z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="balance-scale" class="svg-inline--fa fa-balance-scale fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M256 336h-.02c0-16.18 1.34-8.73-85.05-181.51-8.83-17.65-25.89-26.49-42.95-26.49-17.04 0-34.08 8.82-42.92 26.49C-2.06 328.75.02 320.33.02 336H0c0 44.18 57.31 80 128 80s128-35.82 128-80zM83.24 265.13c11.4-22.65 26.02-51.69 44.46-89.1.03-.01.13-.03.29-.03l.02-.04c19.82 39.64 35.03 69.81 46.7 92.96 11.28 22.38 19.7 39.12 25.55 51.08H55.83c6.2-12.68 15.24-30.69 27.41-54.87zM528 464H344V155.93c27.42-8.67 48.59-31.36 54.39-59.93H528c8.84 0 16-7.16 16-16V64c0-8.84-7.16-16-16-16H393.25C380.89 19.77 352.79 0 320 0s-60.89 19.77-73.25 48H112c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h129.61c5.8 28.57 26.97 51.26 54.39 59.93V464H112c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zM320 112c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32zm319.98 224c0-16.18 1.34-8.73-85.05-181.51-8.83-17.65-25.89-26.49-42.95-26.49-17.04 0-34.08 8.82-42.92 26.49-87.12 174.26-85.04 165.84-85.04 181.51H384c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02zm-200.15-16c6.19-12.68 15.23-30.69 27.4-54.87 11.4-22.65 26.02-51.69 44.46-89.1.03-.01.13-.03.29-.03l.02-.04c19.82 39.64 35.03 69.81 46.7 92.96 11.28 22.38 19.7 39.12 25.55 51.08H439.83z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="server" class="svg-inline--fa fa-server fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M424 400c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24zm-88-24c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm64-144c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm176-72a47.758 47.758 0 0 1-6.438 24A47.758 47.758 0 0 1 512 208v96a47.758 47.758 0 0 1-6.438 24A47.758 47.758 0 0 1 512 352v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96a47.758 47.758 0 0 1 6.438-24A47.758 47.758 0 0 1 0 304v-96a47.758 47.758 0 0 1 6.438-24A47.758 47.758 0 0 1 0 160V64c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v96zm-464 0h416V64H48v96zm416 48H48v96h416v-96zm0 144H48v96h416v-96zm-64-216c13.255 0 24-10.745 24-24s-10.745-24-24-24-24 10.745-24 24 10.745 24 24 24zm-64 0c13.255 0 24-10.745 24-24s-10.745-24-24-24-24 10.745-24 24 10.745 24 24 24z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="rabbit-fast" class="svg-inline--fa fa-rabbit-fast fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M598.33 189.44c-1.98-1.4.26.02-41.42-25.23-1.44-8.79-3.37-17.75-5.76-26.67C542.64 105.8 516.85 32 461.17 32c-5.01 0-9.99.65-14.8 1.95-18.5 4.96-31.84 17.01-39.68 34.91-8.84-3.03-17.89-4.86-26.88-4.86-16.51 0-31.68 6.07-42.71 17.1-5.7 5.7-14.96 17.64-16.74 36.22C292.78 103.85 266.77 96 239.89 96c-40.75 0-77.54 18.47-112.37 55.99-13.71-10.22-30.11-16-47.53-16-44.19 0-80 35.75-80 79.99 0 44.19 35.76 79.99 80 79.99 10.98 0 21.54-2.34 31.33-6.55 7.3 11.89 8.74 12.68 51.15 59.01l-9.54 5.16c-15.62 10.4-24.94 27.82-24.94 46.59v23.73c0 20.19 10.44 38.29 27.88 48.42 8.78 5.11 18.44 7.66 28.12 7.66 9.53 0 19.06-2.48 27.78-7.45l42.21-24.12 14.6 15.95a48.01 48.01 0 0 0 35.41 15.59h160c26.51 0 48-21.49 48-48 0-26.14-12.6-49.39-32.05-64h61.07c54.58 0 98.98-44.12 98.98-98.35.01-31.78-15.57-61.76-41.66-80.17zM95.87 243.1c-19.31 11.27-34.01.01-38.5-4.48-12.5-12.5-12.5-32.76 0-45.25 6.69-6.7 26.57-16.99 44.22-.69-5.94 16.23-7.56 33.47-5.72 50.42zm92.1 187.76c-3.5 2.02-6.5.81-8-.02-1.47-.88-3.97-2.92-3.97-6.92v-23.73c0-2.69 1.34-5.17 1.62-5.5l18.2-9.81 24.94 27.24-32.79 18.74zm353.05-110.88H448l-48.06 20.03c-.35-48.13-31.81-90.94-76.81-104.27l-36.31-10.77c-12.81-3.75-26.06 3.5-29.81 16.19-3.78 12.72 3.47 26.08 16.19 29.84l36.31 10.76c25.03 7.41 42.5 31.69 42.5 59.03v59.18h80c17.66 0 32 14.36 32 32H304L159.86 274.5c-22.36-24.22-22.66-61.37-.81-86.05C186.71 157.21 212.34 144 239.9 144c52.91 0 112.95 48.69 208.11 111.99 0-18.85-.38-22.24 3.75-33.12-13.16-6.88-28.53-18.32-43.38-33.17-30.93-30.92-47.64-64.35-37.33-74.65 10.74-10.74 45.13 7.8 74.66 37.32 2.58 2.58 4.9 5.18 7.28 7.78-10.27-40.77-7.88-76.17 5.81-79.84 14.11-3.8 34.71 27.54 45.99 69.65 4.37 16.3 6.67 31.8 7.1 44.98 2.6.84 5.2 1.56 7.79 2.82l50.98 30.89c13.4 9.45 21.35 24.71 21.35 40.97-.01 27.82-22.84 50.36-50.99 50.36zM512 239.99c-8.84 0-16 7.16-16 16s7.16 16 16 16 16-7.16 16-16-7.16-16-16-16z"></path></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="key" class="svg-inline--fa fa-key fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M320 48c79.529 0 144 64.471 144 144s-64.471 144-144 144c-18.968 0-37.076-3.675-53.66-10.339L224 368h-32v48h-48v48H48v-96l134.177-134.177A143.96 143.96 0 0 1 176 192c0-79.529 64.471-144 144-144m0-48C213.965 0 128 85.954 128 192c0 8.832.602 17.623 1.799 26.318L7.029 341.088A24.005 24.005 0 0 0 0 358.059V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-24h24c13.255 0 24-10.745 24-24v-20l40.049-40.167C293.106 382.604 306.461 384 320 384c106.035 0 192-85.954 192-192C512 85.965 426.046 0 320 0zm0 144c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"></path></svg>

Before

Width:  |  Height:  |  Size: 804 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="projector" class="svg-inline--fa fa-projector fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M307.72 133.65a16 16 0 0 0 22.63 0l11.31-11.31a16 16 0 0 0 0-22.62l-67.88-67.89a16 16 0 0 0-22.63 0l-11.31 11.31a16 16 0 0 0 0 22.63zM408 128h16a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16h-16a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16zm93.65 5.65a16 16 0 0 0 22.63 0l67.88-67.88a16 16 0 0 0 0-22.63l-11.31-11.31a16 16 0 0 0-22.63 0l-67.88 67.89a16 16 0 0 0 0 22.62zM112 296a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm480-104H480.58c-19.51-9.89-41.25-16-64.58-16s-45.07 6.11-64.58 16H48a48 48 0 0 0-48 48v160a48 48 0 0 0 48 48h16l13 51.88A16 16 0 0 0 92.49 512h23A16 16 0 0 0 131 499.88L144 448h207.42c19.51 9.89 41.25 16 64.58 16s45.07-6.11 64.58-16H496l13 51.88A16 16 0 0 0 524.49 512h23A16 16 0 0 0 563 499.88L576 448h16a48 48 0 0 0 48-48V240a48 48 0 0 0-48-48zM296.38 400H48V240h248.38a143.45 143.45 0 0 0 0 160zM416 416a96 96 0 1 1 96-96 96.14 96.14 0 0 1-96 96zm176-16h-56.38a143.45 143.45 0 0 0 0-160H592zM176 296a24 24 0 1 0 24 24 24 24 0 0 0-24-24z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="traffic-light-go" class="svg-inline--fa fa-traffic-light-go fa-w-12" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M384 192h-48v-45.31c28.57-16.63 48-47.24 48-82.69h-48V32c0-17.67-14.33-32-32-32H80C62.33 0 48 14.33 48 32v32H0c0 35.44 19.43 66.05 48 82.69V192H0c0 35.44 19.43 66.05 48 82.69V320H0c0 37.73 21.97 70.05 53.63 85.74C70.3 466.84 125.62 512 192 512s121.7-45.16 138.37-106.26C362.03 390.05 384 357.73 384 320h-48v-45.31c28.57-16.64 48-47.25 48-82.69zm-96 176c0 52.93-43.06 96-96 96s-96-43.07-96-96V48h192v320zm-96-192c26.51 0 48-21.49 48-48s-21.49-48-48-48-48 21.49-48 48 21.49 48 48 48zm0-72c13.23 0 24 10.77 24 24s-10.77 24-24 24-24-10.77-24-24 10.77-24 24-24zm0 200c26.51 0 48-21.49 48-48s-21.49-48-48-48-48 21.49-48 48 21.49 48 48 48zm0-72c13.23 0 24 10.77 24 24s-10.77 24-24 24-24-10.77-24-24 10.77-24 24-24zm0 200c26.51 0 48-21.49 48-48s-21.49-48-48-48-48 21.49-48 48 21.49 48 48 48z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="palette" class="svg-inline--fa fa-palette fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M128 224c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.4-32-32-32zM418.6 58.1C359.2 9.3 281.3-10 204.6 5 104.9 24.4 24.7 104.2 5.1 203.7c-16.7 84.2 8.1 168.3 67.8 230.6 47.3 49.4 109.7 77.8 167.9 77.8 8.8 0 17.5-.6 26.1-2 24.2-3.7 44.6-18.7 56.1-41.1 12.3-24 12.3-52.7.2-76.6-6.1-12-5.5-26.2 1.8-38 7-11.8 18.7-18.4 32-18.4h72.2c46.4 0 82.8-35.7 82.8-81.3-.2-76.4-34.3-148.1-93.4-196.6zM429.2 288H357c-29.9 0-57.2 15.4-73 41.3-16 26.1-17.3 57.8-3.6 84.9 5.1 10.1 5.1 22.7-.2 32.9-2.6 5-8.7 13.7-20.6 15.6-49.3 7.7-108.9-16.6-152-61.6-48.8-50.9-69-119.4-55.4-188 15.9-80.6 80.8-145.3 161.6-161 62.6-12.3 126.1 3.5 174.3 43.1 48.1 39.5 75.7 97.6 75.9 159.6 0 18.6-15.3 33.2-34.8 33.2zM160 128c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.4-32-32-32zm96-32.1c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32c0-17.6-14.3-32-32-32zm96 32.1c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="debug" class="svg-inline--fa fa-debug fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M117.75 271a16 16 0 1 0 4.5 31.68l42.75-6.09a90.21 90.21 0 0 0 10.81 39l-35.51 23.69a16 16 0 1 0 17.7 26.61l37.64-25.1a87.82 87.82 0 0 0 83.24 19.94L162.77 264.58zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.28 0-200-89.72-200-200a198.86 198.86 0 0 1 42.81-123.25l280.44 280.44A198.86 198.86 0 0 1 256 456zm157.19-76.75L345 311.08a89.64 89.64 0 0 0 2-14.49l42.73 6.11a16 16 0 1 0 4.5-31.68l-46.82-6.69v-24.65l46.82-6.7a16 16 0 1 0-4.5-31.68l-43.52 6.22a90.15 90.15 0 0 0-10-31.1l35.51-23.69A16 16 0 1 0 354 126.11l-37.64 25.1a90.27 90.27 0 0 0-126.08 5.1l-57.5-57.5A198.86 198.86 0 0 1 256 56c110.28 0 200 89.72 200 200a198.86 198.86 0 0 1-42.81 123.25z"></path></svg>

Before

Width:  |  Height:  |  Size: 919 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="user-visor" class="svg-inline--fa fa-user-visor fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M313.59375,304c-28.6875,0-42.5,16-89.59375,16s-60.8125-16-89.59375-16A134.43133,134.43133,0,0,0,0,438.40625V464a48.01238,48.01238,0,0,0,48,48H400a48.01238,48.01238,0,0,0,48-48V438.40625A134.43133,134.43133,0,0,0,313.59375,304ZM400,464H48V438.40625A86.55945,86.55945,0,0,1,134.40625,352C149,352,172.6875,368,224,368c51.6875,0,74.90625-16,89.59375-16A86.55945,86.55945,0,0,1,400,438.40625ZM322.44141,362.66406a3.53,3.53,0,0,0-2.69532,1.23633c-17.61132,20.42969-28.27734,47.19531-31.72265,79.55664a3.55509,3.55509,0,0,0,5.72265,3.18164c22.084-17.18164,30-21.168,32.918-22.05664a5.98,5.98,0,0,1,1.22266-.334c2.332,2.07031,7.27734,7.627,17.666,22.252a3.51185,3.51185,0,0,0,2.88868,1.5,3.63354,3.63354,0,0,0,1.14062-.18164,3.56782,3.56782,0,0,0,2.416-3.48633c-1.02735-31.40234-10.02735-58.4043-26.72266-80.26562A4.00227,4.00227,0,0,0,322.44141,362.66406ZM88.33789,190.45312C107.73828,247.05078,160.82422,288,224,288s116.26172-40.94922,135.66211-97.54688C373.52734,186.94336,384,174.95508,384,160V96a31.99908,31.99908,0,0,0-32-32h-8.31641a143.90751,143.90751,0,0,0-239.36718,0H96A31.99908,31.99908,0,0,0,64,96v64C64,174.95508,74.47266,186.94336,88.33789,190.45312ZM224,240c-35.37305,0-65.99023-19.44531-82.64453-48H306.64453C289.99023,220.55469,259.37305,240,224,240Zm0-192a95.35439,95.35439,0,0,1,52.86719,16H171.13281A95.35439,95.35439,0,0,1,224,48ZM112,112H336v32H112Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="cloud-upload-alt" class="svg-inline--fa fa-cloud-upload-alt fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M395.5 267.5l-99-99c-4.7-4.7-12.3-4.7-17 0l-99 99c-7.6 7.6-2.2 20.5 8.5 20.5h67v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-84h67c10.7 0 16.1-12.9 8.5-20.5zm148.2-67.4C539.7 142.1 491.4 96 432 96c-7.6 0-15.1.8-22.4 2.3C377.7 58.3 328.1 32 272 32c-84.6 0-155.5 59.7-172.3 139.8C39.9 196.1 0 254.4 0 320c0 88.4 71.6 160 160 160h336c79.5 0 144-64.5 144-144 0-61.8-39.2-115.8-96.3-135.9zM496 432H160c-61.9 0-112-50.1-112-112 0-56.4 41.7-103.1 96-110.9V208c0-70.7 57.3-128 128-128 53.5 0 99.3 32.8 118.4 79.4 11.2-9.6 25.7-15.4 41.6-15.4 35.3 0 64 28.7 64 64 0 11.8-3.2 22.9-8.8 32.4 2.9-.3 5.9-.4 8.8-.4 53 0 96 43 96 96s-43 96-96 96z"></path></svg>

Before

Width:  |  Height:  |  Size: 883 B

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="rocket-launch" class="svg-inline--fa fa-rocket-launch fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M35.68523,352.06641C9.82784,377.91992-2.94948,442.59375.5759,511.41016c69.11514,3.55859,133.61115-9.35157,159.365-35.10547,40.289-40.2793,42.8769-93.98633,6.31054-130.54883C129.68706,309.19727,75.97033,311.78516,35.68523,352.06641Zm81.6327,84.03125c-8.58592,8.584-30.08394,12.88672-53.11907,11.69922-1.17382-22.93555,3.084-44.49219,11.70311-53.10938,13.42772-13.42578,31.33-14.28906,43.51752-2.10352C131.607,404.77148,130.74565,422.67188,117.31793,436.09766ZM505.16311,19.29688c-1.17578-5.4629-6.98827-11.26563-12.45115-12.4336C460.6163,0,435.464,0,410.4191,0,307.20049,0,245.30018,55.20312,199.09126,128H94.88827c-16.29685,0-35.59956,11.92383-42.88861,26.49805L2.57785,253.29688A28.4,28.4,0,0,0,.06223,264,24.00826,24.00826,0,0,0,24.0661,288h103.953a96.00635,96.00635,0,0,1,96.01354,96V488a24.00826,24.00826,0,0,0,24.00388,24,28.53983,28.53983,0,0,0,10.70311-2.51562l98.74791-49.40626c14.56053-7.28515,26.47457-26.56445,26.47457-42.84374V312.79688c72.5878-46.3125,128.01936-108.40626,128.01936-211.09376C512.07521,76.55273,512.07521,51.40234,505.16311,19.29688ZM358.13792,272.332c-25.332,16.16211-7.50585,6.74024-99.31627,52.209a144.4818,144.4818,0,0,0-71.41006-71.36719c45.373-91.6836,35.89643-73.75,52.21282-99.45313C286.66341,79.61719,337.74146,48,410.4191,48c17.64841,0,33.541,0,51.373,2.248,2.30468,18.26367,2.24413,34.46875,2.18163,51.45507C463.97371,173.97266,432.32141,225.002,358.13792,272.332ZM368.05587,104a40,40,0,1,0,40.00581,40A40.01947,40.01947,0,0,0,368.05587,104Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="comet" class="svg-inline--fa fa-comet fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M308.422,263.93781l-61.1094-8.92187L219.961,199.48281a13.37629,13.37629,0,0,0-24.01563,0l-27.35353,55.53313-61.10939,8.92187a13.40072,13.40072,0,0,0-7.40625,22.86911l44.26173,43.166-10.4961,61.01164a13.38,13.38,0,0,0,19.416,14.11913l54.69533-28.81051,54.69533,28.81051a13.386,13.386,0,0,0,19.416-14.11913L271.631,329.97288l44.25392-43.166A13.4298,13.4298,0,0,0,308.422,263.93781ZM502.34978,9.75648a32.86732,32.86732,0,0,0-33.0879-8.29687c-28.4004,8.5-94.98245,29.18356-153.252,52.291a38.60717,38.60717,0,0,0-53.8965-20.29489c-42.21095,21.998-146.28325,79.17959-203.461,136.283-78.20315,78.19522-78.20315,205.36889,0,283.56411a200.55452,200.55452,0,0,0,283.53916,0c57.084-56.99407,114.38481-161.28105,136.38091-203.36889a38.52636,38.52636,0,0,0-20.40235-53.90033c23.1836-58.49407,43.8047-124.89438,52.30275-153.18731A32.66975,32.66975,0,0,0,502.34978,9.75648Zm-71.5801,227.97433c-23.90235,44.79291-73.98635,133.18929-122.47661,181.57594a152.39983,152.39983,0,0,1-215.64655,0c-59.39456-59.49406-59.39456-156.1873,0-215.68137,49.084-49.08783,141.754-101.08191,181.6524-122.3768,2.446,8.03684,4.29138,14.41977,10.998,37.38667l24.90236-10.68749c47.584-20.40427,107.3848-40.19917,146.28325-52.40032-12.2168,38.79292-31.9004,98.39636-52.3965,146.28107l-10.7168,24.90426C421.60232,235.09874,424.78362,236.06512,430.76968,237.73081Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="language" class="svg-inline--fa fa-language fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M160.3 203.8h-.5s-4.3 20.9-7.8 33l-11 37.3h37.9l-10.7-37.3c-3.6-12.1-7.9-33-7.9-33zM616 96H24c-13.3 0-24 10.7-24 24v272c0 13.3 10.7 24 24 24h592c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zM233.2 352h-22.6a12 12 0 0 1-11.5-8.6l-9.3-31.7h-59.9l-9.1 31.6c-1.5 5.1-6.2 8.7-11.5 8.7H86.8c-8.2 0-14-8.1-11.4-15.9l57.1-168c1.7-4.9 6.2-8.1 11.4-8.1h32.2c5.1 0 9.7 3.3 11.4 8.1l57.1 168c2.6 7.8-3.2 15.9-11.4 15.9zM600 376H320V136h280zM372 228h110.8c-6.3 12.8-15.1 25.9-25.9 38.5-6.6-7.8-12.8-15.8-18.3-24-3.5-5.3-10.6-6.9-16.1-3.6l-13.7 8.2c-5.9 3.5-7.6 11.3-3.8 17 6.5 9.7 14.4 20.1 23.5 30.6-9 7.7-18.6 14.8-28.7 21.2-5.4 3.4-7.1 10.5-3.9 16l7.9 13.9c3.4 5.9 11 7.9 16.8 4.2 12.5-7.9 24.6-17 36-26.8 10.7 9.6 22.3 18.6 34.6 26.6 5.8 3.7 13.6 1.9 17-4.1l8-13.9c3.1-5.5 1.5-12.5-3.8-16-9.2-6-18.4-13.1-27.2-20.9 1.5-1.7 2.9-3.3 4.3-5 17.1-20.6 29.6-41.7 36.8-62H540c6.6 0 12-5.4 12-12v-16c0-6.6-5.4-12-12-12h-64v-16c0-6.6-5.4-12-12-12h-16c-6.6 0-12 5.4-12 12v16h-64c-6.6 0-12 5.4-12 12v16c0 6.7 5.4 12.1 12 12.1z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="portal-enter" class="svg-inline--fa fa-portal-enter fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M416,0c-38.68751,0-83.877,34.86808-93.9043,188.8126l-.002-.00586a88.19428,88.19428,0,0,0-64.8125-60.23254l-78.25-17.70258a87.4657,87.4657,0,0,0-73.25,16.21825l-48.375,37.35824a24.00841,24.00841,0,1,0,29.375,37.98321l48.375-37.37386a40.34188,40.34188,0,0,1,33.3125-7.37477l14.875,3.37489-35.3125,87.34109a55.77113,55.77113,0,0,0,23,68.90415l83.78124,50.5922a8.84284,8.84284,0,0,1,3.84376,6.84354,8.72041,8.72041,0,0,1-.3125,2.20306L225.06249,481.40718a23.97436,23.97436,0,0,0,16.46876,29.671,24.99565,24.99565,0,0,0,6.625.92185,23.98662,23.98662,0,0,0,23.0625-17.42134l33.3125-104.46557A56.10341,56.10341,0,0,0,279.625,326.7869L227.78125,295.491l41.9375-104.79367a39.09378,39.09378,0,0,1,6.40625,12.06213l13.96875,45.9361c7.21874,23.67115,28.6875,39.04568,53.40625,39.13943l48.40625.15624H392a23.986,23.986,0,0,0,24-23.90552c.06249-13.26522-10.65625-23.48366-23.93751-23.53053l-23.88085-.084C370.01953,132.87485,390.69922,47.99854,416,47.99854c26.50977,0,48,93.12215,48,207.99365s-21.49023,207.99365-48,207.99365c-21.35352,0-39.42773-60.45909-45.66016-143.99561h-48.4375C328.01367,418.1845,350.87305,511.98438,416,511.98438c43.79492,0,96-44.41271,96-255.99219C512,139.20864,495.3457,0,416,0ZM272.15625,95.99707A47.99855,47.99855,0,1,0,224.125,47.99854,48.02832,48.02832,0,0,0,272.15625,95.99707Zm-146,220.85264L106.3125,363.12954a8.0132,8.0132,0,0,1-7.34375,4.85923H24a23.99927,23.99927,0,1,0,0,47.99854H98.96875a55.99645,55.99645,0,0,0,51.5-33.93647L164,350.44243l-9.5625-5.76545A87.55881,87.55881,0,0,1,126.15625,316.84971Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

Some files were not shown because too many files have changed in this diff Show More