Skip to content

Commit

Permalink
Merge pull request #38 from Lissy93/feature_workspace-view
Browse files Browse the repository at this point in the history
Feature workspace view
  • Loading branch information
Lissy93 authored Jun 18, 2021
2 parents f03b6c4 + caaf8b1 commit b5f8c85
Show file tree
Hide file tree
Showing 27 changed files with 588 additions and 42 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWAREOR THE
OR OTHER DEALINGS IN THE SOFTWARE.
```
#### Author 🦄
<p align="right"><img width="200" src="https://i.ibb.co/FnxqTfx/aht-bot-round.png" alt="Alicia Sykes"></p>
Developed by [Alicia Sykes](https://aliciasykes.com) ([@Lissy93](https://github.com/lissy93)) in 2021.
- **PGP Key**: [`0688 F8D3 4587 D954 E9E5 1FB8 FEDB 68F5 5C02 83A7`](https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7)
- **BTC Address**: `3853bSxupMjvxEYfwGDGAaLZhTKxB2vEVC`
**[⬆️ Back to Top](#dashy)**
---
Expand Down
16 changes: 15 additions & 1 deletion docs/backup-restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ Maximum of 24mb of storage per user. Please do not repeatedly hit the endpoint,
- 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
Expand All @@ -66,7 +80,7 @@ async function handleRequest(request) {
}
```

- For the code used for Dashy's cloud service, see [here](https://notes.aliciasykes.com/p/j2F1deljv1)
- For the code used for Dashy's cloud service, see [here](https://gist.github.com/Lissy93/d19b43d50f30e02fa25f349cf5cb5ed8#file-index-js)


#### Commands
Expand Down
8 changes: 5 additions & 3 deletions docs/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ All fields are optional, unless otherwise stated.
**`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`)
**`layout`** | `string` | _Optional_ | App layout, either `horizontal`, `vertical`, `auto` or `sidebar`. Defaults to `auto`. This specifies the layout and direction of how sections are positioned on the home screen. This can also be modified from the UI.
**`iconSize`** | `string` | _Optional_ | The size of link items / icons. Can be either `small`, `medium,` or `large`. Defaults to `medium`. This can also be set directly from the UI.
**`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
**`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
Expand Down Expand Up @@ -104,9 +106,9 @@ All fields are optional, unless otherwise stated.
**`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`.
**`layout`** | `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 `layout` 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 `layout` is set to `grid`. Must be a whole number between `1` and `12`
**`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`

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

Expand Down
3 changes: 2 additions & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ Click one of the links below, to open an issue:
### Contributors
![Auto-generated contributors](https://raw.githubusercontent.com/Lissy93/dashy/03fbaf35ff4653d16a622cfce00a1347c13d0192/docs/assets/CONTRIBUTORS.svg)
![Auto-generated contributors](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/CONTRIBUTORS.svg)
### Star-Gazers Over Time
Expand Down
27 changes: 26 additions & 1 deletion docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [Basic Commands](#basic-commands)
- [Healthchecks](#healthchecks)
- [Monitoring](#logs-and-performance)
- [Auto Starting](#auto-starting-at-system-boot)
- [Updating](#updating)
- [Updating Docker Container](#updating-docker-container)
- [Automating Docker Updates](#automatic-docker-updates)
Expand Down Expand Up @@ -49,6 +50,16 @@ You can also build and deploy the Docker container from source.
- Edit the `./public/conf.yml` file and take a look at the `docker-compose.yml`
- Start the container: `docker compose up`

### Other Container Engines

Docker isn't the only host application capable of running standard Linux containers - [Podman](http://podman.io) is another popular option. Unlike Docker, Podman does not rely on a daemon to be running on your host system. This means there is no single point of failure and it can also support rootless containers, which is perfect for Dashy as it does not require any sudo privileges. Podman was developed by RedHat, and it's source code is written in Go, and published on [GitHub](https://github.com/containers/podman).

Installation of the podman is really easy, as it's repository is available for most package managers (for example; Arch: `sudo pacman -S podman`, Debian/ Ubuntu: `sudo apt-get install podman`, Gentoo: `sudo emerge app-emulation/podman`, and MacOS: `brew install podman`). For more info, check out the [podman installation docs](https://podman.io/getting-started/installation). If you are using Windows, then take a look at Brent Baude's article on [Running Podman on WSL](https://www.redhat.com/sysadmin/podman-windows-wsl2). Since it's CLI is pretty much identical to that of Dockers, Podman's learning curve is very shallow.

To run Dashy with Podman, just replace `docker` with `podman` in the above instructions. E.g. `podman run -p 8080:80 lissy93/dashy`

It's worth noting that Podman isn't the only container running alternative, there's also [`rkt`](https://www.openshift.com/learn/topics/rkt), [`runc`](https://github.com/opencontainers/runc), [`containerd`](https://containerd.io/) and [`cri-o`](https://cri-o.io/). Dashy has not been tested with any of these engines, but it should work just fine.


### Deploy 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.
Expand Down Expand Up @@ -187,11 +198,25 @@ To restart unhealthy containers automatically, check out [Autoheal](https://hub.

### 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.

You can also view logs, resource usage and other info as well as manage your Docker workflow in third-party Docker management apps. For example [Portainer](https://github.com/portainer/portainer) an all-in-one management web UI for Docker and Kubernetes, or [LazyDocker](https://github.com/jesseduffield/lazydocker) a terminal UI for Docker container management and monitoring.
##### 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.

**[⬆️ Back to Top](#deployment)**

Expand Down
1 change: 1 addition & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
- [User Guide](/docs/user-guide.md)
- [Troubleshooting](/docs/troubleshooting.md)
- [Backup & Restore](/docs/backup-restore.md)
- [Status Indicators](/docs/status-indicators.md)
- [Theming](/docs/theming.md)
- [Authentication](/docs/authentication.md)
4 changes: 4 additions & 0 deletions docs/theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ You can target specific elements on the UI with these variables. All are optiona
- `--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`

#### Non-Color Variables
- `--outline-color` - Used to outline focused or selected elements
Expand Down
1 change: 1 addition & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default {
<style lang="scss">
@import '@/styles/global-styles.scss';
@import '@/styles/color-palette.scss';
@import '@/styles/dimensions.scss';
@import '@/styles/color-themes.scss';
@import '@/styles/typography.scss';
Expand Down
2 changes: 1 addition & 1 deletion src/components/LinkItems/ItemGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default {
return this.displayData.itemSize || this.itemSize;
},
isGridLayout() {
return this.displayData.layout === 'grid'
return this.displayData.sectionLayout === 'grid'
|| !!(this.displayData.itemCountX || this.displayData.itemCountY);
},
gridStyle() {
Expand Down
11 changes: 9 additions & 2 deletions src/components/LinkItems/ItemIcon.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<div class="item-icon">
<i v-if="iconType === 'font-awesome'" :class="`${icon} ${size}`" ></i>
<img v-else-if="icon" :src="iconPath" @error="imageNotFound"
:class="`tile-icon ${size} ${broken ? 'broken' : ''}`"
Expand Down Expand Up @@ -98,9 +98,16 @@ export default {

<style lang="scss">
.tile-icon {
width: 60px;
width: 2rem;
// filter: var(--item-icon-transform);
border-radius: var(--curve-factor);
&.broken { display: none; }
&.small {
width: 1.5rem;
}
&.large {
width: 3rem;
}
}
i.fas, i.fab, i.far, i.fal, i.fad {
font-size: 2rem;
Expand Down
3 changes: 3 additions & 0 deletions src/components/PageStrcture/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export default {
<style scoped lang="scss">
footer {
position: fixed;
width: 100%;
bottom: 0;
padding: 0.25rem;
text-align: center;
color: var(--medium-grey);
Expand Down
1 change: 1 addition & 0 deletions src/components/Settings/ThemeSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
}
},
methods: {
/* Sets the theme, by updating data-theme attribute on the html tag */
setLocalTheme(newTheme) {
const htmlTag = document.getElementsByTagName('html')[0];
if (htmlTag.hasAttribute('data-theme')) htmlTag.removeAttribute('data-theme');
Expand Down
90 changes: 90 additions & 0 deletions src/components/Workspace/SideBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<template>
<nav class="side-bar">
<div v-for="(section, index) in sections" :key="index">
<div @click="openSection(index)" class="side-bar-item-container">
<SideBarItem
class="item"
:icon="section.icon"
:title="section.name"
/>
</div>
<transition name="slide">
<SideBarSection
v-if="isOpen[index]"
:items="section.items"
@launch-app="launchApp"
/>
</transition>
</div>
</nav>
</template>

<script>
import SideBarItem from '@/components/Workspace/SideBarItem.vue';
import SideBarSection from '@/components/Workspace/SideBarSection.vue';
export default {
name: 'SideBar',
inject: ['config'],
props: {
sections: Array,
},
data() {
return {
isOpen: new Array(this.sections.length).fill(false),
};
},
components: {
SideBarItem,
SideBarSection,
},
methods: {
/* Toggles the section clicked, and closes all other sections */
openSection(index) {
this.isOpen = this.isOpen.map((val, ind) => (ind !== index ? false : !val));
},
launchApp(url) {
this.$emit('launch-app', url);
},
},
};
</script>

<style lang="scss" scoped>
@import '@/styles/media-queries.scss';
@import '@/styles/style-helpers.scss';
nav.side-bar {
position: fixed;
display: flex;
flex-direction: column;
background: var(--side-bar-background);
color: var(--side-bar-color);
height: 100%;
width: var(--side-bar-width);
text-align: center;
overflow: auto;
@extend .scroll-bar;
.side-bar-item-container {
z-index: 5;
}
.item:not(:last-child) {
border-bottom: 1px dashed var(--side-bar-color);
z-index: 5;
}
}
.slide-leave-active,
.slide-enter-active {
transition: all 0.1s ease-in-out;
}
.slide-enter {
transform: translate(0, -80%);
}
.slide-leave-to {
transform: translate(0, -80%);
}
</style>
64 changes: 64 additions & 0 deletions src/components/Workspace/SideBarItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div @click="itemClicked()"
:class="`side-bar-item ${icon ? 'w-icon' : 'text-only'}`" v-tooltip="tooltip">
<Icon v-if="icon" :icon="icon" size="small" :url="url" />
<p class="small-title" v-else>{{ title }}</p>
</div>
</template>

<script>
import Icon from '@/components/LinkItems/ItemIcon.vue';
export default {
name: 'SideBarItem',
inject: ['config'],
props: {
icon: String,
title: String,
url: String,
click: Function,
},
components: {
Icon,
},
methods: {
itemClicked() {
if (this.url) this.$emit('launch-app', this.url);
},
},
data() {
return {
tooltip: {
disabled: !this.title,
content: this.title,
trigger: 'hover focus',
hideOnTargetClick: true,
html: false,
placement: 'right-start',
delay: { show: 800, hide: 1000 },
},
};
},
};
</script>

<style lang="scss" scoped>
@import '@/styles/media-queries.scss';
@import '@/styles/style-helpers.scss';
div.side-bar-item {
color: var(--side-bar-color);
background: var(--side-bar-background);
text-align: center;
&.text-only {
background: none;
border: none;
box-shadow: none;
p.small-title {
margin: 0.1rem auto;
font-size: 0.6rem;
}
}
}
</style>
Loading

1 comment on commit b5f8c85

@vercel
Copy link

@vercel vercel bot commented on b5f8c85 Jun 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.