mirror of https://github.com/bastienwirtz/homer
Merge branch 'main' into linkding_support
# Conflicts: # docs/customservices.mdpull/895/head
commit
2024297f61
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
|
@ -0,0 +1,359 @@
|
|||
{
|
||||
"$id": "https://raw.githubusercontent.com/bastienwirtz/homer/main/.schema/config-schema.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"description": "https://github.com/bastienwirtz/homer/blob/main/docs/configuration.md",
|
||||
"examples": [],
|
||||
"title": "Homer Dashboard configuration",
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
"Colors": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"light": {
|
||||
"$ref": "#/definitions/ColorSet"
|
||||
},
|
||||
"dark": {
|
||||
"$ref": "#/definitions/ColorSet"
|
||||
}
|
||||
},
|
||||
"title": "Colors"
|
||||
},
|
||||
"ColorSet": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"highlight-primary": {
|
||||
"type": "string"
|
||||
},
|
||||
"highlight-secondary": {
|
||||
"type": "string"
|
||||
},
|
||||
"highlight-hover": {
|
||||
"type": "string"
|
||||
},
|
||||
"background": {
|
||||
"type": "string"
|
||||
},
|
||||
"card-background": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"text-header": {
|
||||
"type": "string"
|
||||
},
|
||||
"text-title": {
|
||||
"type": "string"
|
||||
},
|
||||
"text-subtitle": {
|
||||
"type": "string"
|
||||
},
|
||||
"card-shadow": {
|
||||
"type": "string"
|
||||
},
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"link-hover": {
|
||||
"type": "string"
|
||||
},
|
||||
"background-image": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Defaults": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"layout": {
|
||||
"enum": [
|
||||
"columns",
|
||||
"list"
|
||||
],
|
||||
"description": "Layout of the dashboard, either 'columns' or 'list'"
|
||||
},
|
||||
"colorTheme": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"light",
|
||||
"dark"
|
||||
],
|
||||
"description": "One of 'auto', 'light', or 'dark'"
|
||||
}
|
||||
},
|
||||
"title": "Defaults"
|
||||
},
|
||||
"Hotkey": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"search": {
|
||||
"type": "string",
|
||||
"description": "hotkey for search, e.g. Shift"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"search"
|
||||
]
|
||||
},
|
||||
"Link": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name as seen in the navbar"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Fontawesome icon"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Url of the link. When #filename is used, it is a link to another homer page, while 'filename' is the name of the config file"
|
||||
},
|
||||
"target": {
|
||||
"type": "string",
|
||||
"description": "html tag target attribute like _blank for a new page"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"title": "Link"
|
||||
},
|
||||
"Message": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"mapping": {
|
||||
"$ref": "#/definitions/Mapping",
|
||||
"description": "Mapping for the content loaded from the URL"
|
||||
},
|
||||
"refreshInterval": {
|
||||
"type": "integer",
|
||||
"description": "The refresh interval in milliseconds for reloading the message url"
|
||||
},
|
||||
"style": {
|
||||
"type": "string",
|
||||
"description": "See https://bulma.io/documentation/components/message/#colors for styling options"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Title of the message box"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Fontawesome icon for the message box"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "HTML content for the message box"
|
||||
}
|
||||
},
|
||||
"title": "Messagebox"
|
||||
},
|
||||
"Mapping": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Mapping"
|
||||
},
|
||||
"Proxy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"useCredentials": {
|
||||
"type": "boolean",
|
||||
"description": "# send cookies & authorization headers when fetching service specific data. Set to `true` if you use an authentication proxy. Can be overrided on service level. "
|
||||
},
|
||||
"headers": {
|
||||
"$ref": "#/definitions/Headers",
|
||||
"description": "send custom headers when fetching service specific data. Can also be set on a service level."
|
||||
}
|
||||
},
|
||||
"title": "Proxy"
|
||||
},
|
||||
"Headers": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Headers"
|
||||
},
|
||||
"Service": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Service name"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Fontawesome icon for the service"
|
||||
},
|
||||
"logo": {
|
||||
"type": "string",
|
||||
"description": "A path to an image can also be provided. Note that icon take precedence if both icon and logo are set."
|
||||
},
|
||||
"class": {
|
||||
"type": "string",
|
||||
"description": "Optional css class to add on the service group. Example 'highlight-purple'"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Item"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"title": "Service"
|
||||
},
|
||||
"Item": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"logo": {
|
||||
"type": "string",
|
||||
"description": "Path to a logo. Alternatively a fa icon can be provided"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Fontawesome icon for the item, alternative for logo"
|
||||
},
|
||||
"subtitle": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string",
|
||||
"description": "Show tag"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"description": "Optional keyword used for searching purpose"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Url of this item"
|
||||
},
|
||||
"target": {
|
||||
"type": "string",
|
||||
"description": "html tag target attribute like _blank for a new page"
|
||||
},
|
||||
"tagstyle": {
|
||||
"type": "string",
|
||||
"description": "Styleclass for the tag"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Optional, loads a specific component that provides extra features. MUST MATCH a file name (without file extension) available in `src/components/services`"
|
||||
}
|
||||
},
|
||||
"title": "Item"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"externalConfig": {
|
||||
"type": "string",
|
||||
"description": "Use external configuration file. Using this will ignore remaining config in this file externalConfig: https://example.com/server-luci/config.yaml"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Title of the dashboard"
|
||||
},
|
||||
"subtitle": {
|
||||
"type": "string",
|
||||
"description": "Subtitle of the dashboard"
|
||||
},
|
||||
"documentTitle": {
|
||||
"type": "string",
|
||||
"description": "Title of the document. When not filled, title (and subtitle will be used)"
|
||||
},
|
||||
"logo": {
|
||||
"type": "string",
|
||||
"description": "Path to logo image"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"description": "Dashboard icon"
|
||||
},
|
||||
"header": {
|
||||
"type": "boolean",
|
||||
"description": "Show header, default is true"
|
||||
},
|
||||
"hotkey": {
|
||||
"$ref": "#/definitions/Hotkey",
|
||||
"description": "Define hotkeys, for example for search"
|
||||
},
|
||||
"footer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "footer Line content. HTML is supported. Set false if you want to hide it."
|
||||
},
|
||||
"columns": {
|
||||
"type": "string",
|
||||
"description": "'auto' or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)",
|
||||
"format": "integer"
|
||||
},
|
||||
"connectivityCheck": {
|
||||
"type": "boolean",
|
||||
"description": "# whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example). You should set it to true when using an authentication proxy, it also reloads the page when a redirection is detected when checking connectivity."
|
||||
},
|
||||
"proxy": {
|
||||
"$ref": "#/definitions/Proxy",
|
||||
"description": "Optional: Proxy / hosting option"
|
||||
},
|
||||
"defaults": {
|
||||
"$ref": "#/definitions/Defaults"
|
||||
},
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"description": "'default' or one of the themes available in 'src/assets/themes'"
|
||||
},
|
||||
"stylesheet": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Will load custom CSS files. Especially useful for custom icon sets. Entries are paths to the stylesheets"
|
||||
},
|
||||
"colors": {
|
||||
"$ref": "#/definitions/Colors"
|
||||
},
|
||||
"message": {
|
||||
"$ref": "#/definitions/Message",
|
||||
"description": "Messagebox"
|
||||
},
|
||||
"links": {
|
||||
"description": "Links in the navigation bar",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Link"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"description": "Services",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Service"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ RUN pnpm build
|
|||
# production stage
|
||||
FROM alpine:3.21
|
||||
|
||||
ARG VERSION_TAG=latest
|
||||
|
||||
LABEL \
|
||||
org.label-schema.schema-version="1.0" \
|
||||
org.label-schema.version="$VERSION_TAG" \
|
||||
|
|
|
@ -26,6 +26,7 @@ within Homer:
|
|||
- [Jellystat](#jellystat)
|
||||
- [Lidarr, Prowlarr, Sonarr, Readarr and Radarr](#lidarr-prowlarr-sonarr-readarr-and-radarr)
|
||||
- [Linkding](#linkding)
|
||||
- [Matrix](#matrix)
|
||||
- [Mealie](#mealie)
|
||||
- [Medusa](#medusa)
|
||||
- [Nextcloud](#nextcloud)
|
||||
|
@ -49,7 +50,9 @@ within Homer:
|
|||
- [Tautulli](#tautulli)
|
||||
- [Tdarr](#tdarr)
|
||||
- [Traefik](#traefik)
|
||||
- [TrueNas Scale](#truenas-scale)
|
||||
- [Uptime Kuma](#uptime-kuma)
|
||||
- [Vaultwarden](#vaultwarden)
|
||||
- [Wallabag](#wallabag)
|
||||
- [What's Up Docker](#whats-up-docker)
|
||||
|
||||
|
@ -298,6 +301,18 @@ This integration supports at max 15 results from Linkding. But you can add it mu
|
|||
query: "#ToDo #Homer"
|
||||
```
|
||||
|
||||
## Matrix
|
||||
|
||||
This service displays a version string instead of a subtitle. The indicator
|
||||
shows if Matrix Server is online, offline
|
||||
|
||||
```yaml
|
||||
- name: "Matrix - Server"
|
||||
type: "Matrix"
|
||||
logo: "assets/tools/sample.png"
|
||||
url: "http://matrix.example.com"
|
||||
```
|
||||
|
||||
## Mealie
|
||||
|
||||
First off make sure to remove an existing `subtitle` as it will take precedence if set.
|
||||
|
@ -470,6 +485,9 @@ This service displays info about the total number of containers managed by your
|
|||
In order to use it, you must be using Portainer version 1.11 or later. Generate an access token from the UI and pass
|
||||
it to the apikey field.
|
||||
By default, every connected environments will be checked. To select specific ones, add an "environments" entry which can be a simple string or an array containing all the selected environments name.
|
||||
### New features:
|
||||
Displays the Portainer version from /api/status
|
||||
Shows online/offline status depending on API reachability
|
||||
|
||||
See <https://docs.portainer.io/api/access#creating-an-access-token>
|
||||
|
||||
|
@ -662,6 +680,18 @@ This service displays a version string instead of a subtitle. Example configurat
|
|||
url: http://traefik.example.com
|
||||
```
|
||||
|
||||
## Truenas Scale
|
||||
|
||||
This service displays a version string instead of a subtitle. Example configuration:
|
||||
|
||||
```yaml
|
||||
- name: "Truenas"
|
||||
type: "TruenasScale"
|
||||
logo: "assets/tools/sample.png"
|
||||
url: "http://truenas.example.com"
|
||||
api_token: "your_api_token"
|
||||
```
|
||||
|
||||
## Uptime Kuma
|
||||
|
||||
Using the Uptime Kuma service you can display info about your instance uptime right on your Homer dashboard.
|
||||
|
@ -676,6 +706,17 @@ The following configuration is available for the UptimeKuma service. Needs v1.13
|
|||
slug: "myCustomDashboard" # Defaults to "default" if not provided.
|
||||
type: "UptimeKuma"
|
||||
```
|
||||
## Vaultwarden
|
||||
|
||||
This service displays a version string instead of a subtitle. The indicator
|
||||
shows if Vaultwarden is online, offline
|
||||
|
||||
```yaml
|
||||
- name: "Vaultwarden - Server"
|
||||
type: "Vaultwarden"
|
||||
logo: "assets/tools/sample.png"
|
||||
url: "http://vaultwarden.example.com"
|
||||
```
|
||||
|
||||
## Wallabag
|
||||
|
||||
|
|
|
@ -78,6 +78,21 @@ Then when Homer reads your config, it will substitute your anchors automatically
|
|||
The end result is that if you want to update the name or style of any particular tag, just update it once, in the tags section!
|
||||
Great if you have a lot of services or a lot of tags!
|
||||
|
||||
## YAML auto complete with a YAML schema
|
||||
|
||||
A lot of editor support auto completion, see <https://www.schemastore.org/json/>
|
||||
The homer schema is available here: <https://raw.githubusercontent.com/bastienwirtz/homer/main/.schema/config-schema.json>
|
||||
|
||||
For example with IntelliJ you can define:
|
||||
|
||||
```yaml
|
||||
# $schema: https://raw.githubusercontent.com/bastienwirtz/homer/main/.schema/config-schema.json
|
||||
```
|
||||
With VSCode you can define it like this:
|
||||
```yaml
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/bastienwirtz/homer/main/.schema/config-schema.json
|
||||
```
|
||||
|
||||
## Remotely edit your config with Code Server
|
||||
|
||||
#### `by @JamiePhonic`
|
||||
|
|
|
@ -14,4 +14,5 @@ if [[ "${INIT_ASSETS}" == "1" ]] && [[ ! -f "/www/assets/config.yml" ]]; then
|
|||
fi
|
||||
|
||||
echo "Starting webserver"
|
||||
exec 3>&1
|
||||
exec lighttpd -D -f /lighttpd.conf
|
||||
|
|
|
@ -18,6 +18,6 @@ export default [
|
|||
},
|
||||
},
|
||||
{
|
||||
ignores: ["*.d.ts", "**/coverage", "**/dist"],
|
||||
ignores: ["**/dist/**", "**/dist-ssr/**", "**/coverage/**"],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -2,7 +2,7 @@ include "/etc/lighttpd/mime-types.conf"
|
|||
include_shell "/etc/lighttpd/ipv6.sh"
|
||||
|
||||
server.port = env.PORT
|
||||
server.modules = ( "mod_alias" )
|
||||
server.modules = ( "mod_alias", "mod_accesslog" )
|
||||
server.username = "lighttpd"
|
||||
server.groupname = "lighttpd"
|
||||
server.document-root = "/www"
|
||||
|
@ -10,3 +10,9 @@ alias.url = ( env.SUBFOLDER => "/www" )
|
|||
server.indexfiles = ("index.html")
|
||||
server.follow-symlink = "enable"
|
||||
server.feature-flags += ( "server.clock-jump-restart" => 0 )
|
||||
server.max-request-field-size = 65535
|
||||
accesslog.filename = "/dev/fd/3"
|
||||
|
||||
# Avoid logging docker healthcheck request
|
||||
$HTTP["remote-ip"] == "127.0.0.1" { accesslog.filename = "" }
|
||||
$HTTP["remote-ip"] == "[::1]" { accesslog.filename = "" }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "homer",
|
||||
"version": "25.02.2",
|
||||
"version": "25.03.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -26,7 +26,7 @@
|
|||
"http-server": "^14.1.1",
|
||||
"prettier": "^3.5.2",
|
||||
"sass-embedded": "^1.85.0",
|
||||
"vite": "^6.1.1",
|
||||
"vite": "^6.1.2",
|
||||
"vite-plugin-pwa": "^0.21.1"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
|
|
989
pnpm-lock.yaml
989
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -171,9 +171,9 @@
|
|||
|
||||
.title {
|
||||
font-size: 1.1em;
|
||||
line-height: 1.2em;
|
||||
line-height: 1.3em;
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 3px;
|
||||
@include ellipsis();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
:href="link.url"
|
||||
:target="link.target"
|
||||
>
|
||||
<i
|
||||
v-if="link.icon"
|
||||
:class="['fa-fw', link.icon, { 'mr-2': link.name }]"
|
||||
></i>
|
||||
<i v-if="link.icon" :class="['fa-fw', link.icon]"></i>
|
||||
{{ link.name }}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -65,3 +62,11 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@media (min-width: 1023px) {
|
||||
i.fa-fw {
|
||||
width: 0.8em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -64,7 +64,7 @@ export default {
|
|||
});
|
||||
},
|
||||
hasFocus: function () {
|
||||
return document.activeElement == this.$refs.search
|
||||
return document.activeElement == this.$refs.search;
|
||||
},
|
||||
setSearchURL: function (value) {
|
||||
const url = new URL(window.location);
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<component :is="component" :item="item" :proxy="proxy"></component>
|
||||
<Generic v-if="isGeneric" :item="item"></Generic>
|
||||
<component :is="component" v-else :item="item" :proxy="proxy"></component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineAsyncComponent } from "vue";
|
||||
import Generic from "./services/Generic.vue";
|
||||
|
||||
const defaultService = "Generic";
|
||||
|
||||
export default {
|
||||
name: "Service",
|
||||
|
@ -13,12 +15,13 @@ export default {
|
|||
proxy: Object,
|
||||
},
|
||||
computed: {
|
||||
isGeneric() {
|
||||
return defaultService === (this.item.type || defaultService);
|
||||
},
|
||||
component() {
|
||||
const type = this.item.type || "Generic";
|
||||
if (type === "Generic") {
|
||||
return Generic;
|
||||
}
|
||||
return defineAsyncComponent(() => import(`./services/${type}.vue`));
|
||||
return defineAsyncComponent(
|
||||
() => import(`./services/${this.item.type}.vue`),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "AdGuardHome",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -15,13 +15,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "CopyToClipboard",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Docuseal",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Emby",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -25,13 +25,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "FreshRSS",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Gitea",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -17,13 +17,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Glances",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -19,13 +19,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Gotify",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -18,13 +18,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Healthchecks",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "HomeAssistant",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -27,13 +27,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Immich",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -20,13 +20,9 @@
|
|||
</template>
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Jellyfin",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -27,13 +27,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Lidarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<Generic :item="item">
|
||||
<template #content>
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">
|
||||
<template v-if="item.subtitle">
|
||||
{{ item.subtitle }}
|
||||
</template>
|
||||
<template v-else-if="versionstring">
|
||||
Version {{ versionstring }}
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
<template #indicator>
|
||||
<div v-if="status" class="status" :class="status">
|
||||
{{ status }}
|
||||
</div>
|
||||
</template>
|
||||
</Generic>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
|
||||
export default {
|
||||
name: "Matrix",
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
},
|
||||
data: () => ({
|
||||
fetchOk: null,
|
||||
versionstring: null,
|
||||
}),
|
||||
computed: {
|
||||
status: function () {
|
||||
return this.fetchOk ? "online" : "offline";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchStatus();
|
||||
},
|
||||
methods: {
|
||||
fetchStatus: async function () {
|
||||
this.fetch("_matrix/federation/v1/version")
|
||||
.then((response) => {
|
||||
this.fetchOk = true;
|
||||
this.versionstring = response.server.version;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.fetchOk = false;
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-title);
|
||||
white-space: nowrap;
|
||||
margin-left: 0.25rem;
|
||||
|
||||
&.online:before {
|
||||
background-color: #94e185;
|
||||
border-color: #78d965;
|
||||
box-shadow: 0 0 5px 1px #94e185;
|
||||
}
|
||||
|
||||
&.offline:before {
|
||||
background-color: #c9404d;
|
||||
border-color: #c42c3b;
|
||||
box-shadow: 0 0 5px 1px #c9404d;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #000;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -19,13 +19,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Mealie",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -33,13 +33,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Medusa",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -22,13 +22,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Mylar",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Nextcloud",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -51,13 +51,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "OctoPrint",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Olivetin",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "OpenHAB",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Paperless",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -19,13 +19,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "PeaNUT",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -27,13 +27,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "PiAlert",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "PiHole",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Ping",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
<template>
|
||||
<Generic :item="item">
|
||||
<template #content>
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">
|
||||
<template v-if="item.subtitle">
|
||||
{{ item.subtitle }}
|
||||
</template>
|
||||
<template v-else-if="versionstring">
|
||||
Version {{ versionstring }}
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
<template #indicator>
|
||||
<div class="notifs">
|
||||
<strong v-if="running > 0" class="notif running" title="Running">
|
||||
|
@ -16,19 +27,18 @@
|
|||
{{ misc }}
|
||||
</strong>
|
||||
</div>
|
||||
<div v-if="status" class="status" :class="status">
|
||||
{{ status }}
|
||||
</div>
|
||||
</template>
|
||||
</Generic>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Portainer",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
@ -36,6 +46,8 @@ export default {
|
|||
data: () => ({
|
||||
endpoints: null,
|
||||
containers: null,
|
||||
fetchOk: null,
|
||||
versionstring: null,
|
||||
}),
|
||||
computed: {
|
||||
running: function () {
|
||||
|
@ -65,9 +77,13 @@ export default {
|
|||
);
|
||||
}).length;
|
||||
},
|
||||
status: function () {
|
||||
return this.fetchOk ? "online" : "offline";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchStatus();
|
||||
this.fetchVersion();
|
||||
},
|
||||
methods: {
|
||||
fetchStatus: async function () {
|
||||
|
@ -103,11 +119,54 @@ export default {
|
|||
|
||||
this.containers = containers;
|
||||
},
|
||||
fetchVersion: async function () {
|
||||
const headers = {
|
||||
"X-Api-Key": this.item.apikey,
|
||||
};
|
||||
this.fetch("/api/status", { headers })
|
||||
.then((response) => {
|
||||
this.fetchOk = true;
|
||||
this.versionstring = response.Version;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.fetchOk = false;
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-title);
|
||||
white-space: nowrap;
|
||||
margin-left: 0.25rem;
|
||||
|
||||
&.online:before {
|
||||
background-color: #94e185;
|
||||
border-color: #78d965;
|
||||
box-shadow: 0 0 5px 1px #94e185;
|
||||
}
|
||||
|
||||
&.offline:before {
|
||||
background-color: #c9404d;
|
||||
border-color: #c42c3b;
|
||||
box-shadow: 0 0 5px 1px #c9404d;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #000;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.notifs {
|
||||
position: absolute;
|
||||
color: white;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
const AlertsStatus = Object.freeze({
|
||||
firing: "firing",
|
||||
|
@ -29,9 +28,6 @@ const AlertsStatus = Object.freeze({
|
|||
|
||||
export default {
|
||||
name: "Prometheus",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -22,13 +22,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Prowlarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -76,13 +76,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Proxmox",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -27,16 +27,12 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
const V3_API = "/api/v3";
|
||||
const LEGACY_API = "/api";
|
||||
|
||||
export default {
|
||||
name: "Radarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -27,15 +27,11 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
const API = "/api/v1";
|
||||
|
||||
export default {
|
||||
name: "Readarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
// Units to add to download and upload rates.
|
||||
const units = ["B", "kiB", "MiB", "GiB"];
|
||||
|
||||
|
@ -48,7 +46,6 @@ const displayRate = (rate) => {
|
|||
|
||||
export default {
|
||||
name: "RTorrent",
|
||||
components: { Generic },
|
||||
props: { item: Object },
|
||||
// Properties for download, upload, torrent count and errors.
|
||||
data: () => ({ dl: null, ul: null, count: null, error: null }),
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "SABnzbd",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -24,13 +24,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Scrutiny",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -28,16 +28,12 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
const V3_API = "/api/v3";
|
||||
const LEGACY_API = "/api";
|
||||
|
||||
export default {
|
||||
name: "Sonarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -15,13 +15,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "SpeedtestTracker",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Tautulli",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -28,13 +28,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Tdarr",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -20,16 +20,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
let currentTheme;
|
||||
const app = document.getElementById("app");
|
||||
|
||||
export default {
|
||||
name: "ThemeChooser",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
props: {
|
||||
item: Object,
|
||||
},
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Traefik",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<Generic :item="item">
|
||||
<template #content>
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">
|
||||
<template v-if="item.subtitle">
|
||||
{{ item.subtitle }}
|
||||
</template>
|
||||
<template v-else-if="versionstring">
|
||||
<span class="is-hidden-touch">Version {{ versionstring }}</span>
|
||||
<span class="is-hidden-desktop"
|
||||
>Version {{ versionstring.split("-").pop() }}</span
|
||||
>
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
<template #indicator>
|
||||
<div v-if="status" class="status" :class="status">
|
||||
{{ status }}
|
||||
</div>
|
||||
</template>
|
||||
</Generic>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
|
||||
export default {
|
||||
name: "TruenasScale",
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
},
|
||||
data: () => ({
|
||||
fetchOk: null,
|
||||
versionstring: null,
|
||||
}),
|
||||
computed: {
|
||||
status: function () {
|
||||
return this.fetchOk ? "online" : "offline";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchStatus();
|
||||
},
|
||||
methods: {
|
||||
fetchStatus: async function () {
|
||||
let headers = {};
|
||||
if (this.item.api_token) {
|
||||
headers["Authorization"] = `Bearer ${this.item.api_token}`;
|
||||
}
|
||||
this.fetch("/api/v2.0/system/version", { headers })
|
||||
.then((response) => {
|
||||
this.fetchOk = true;
|
||||
this.versionstring = response;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.fetchOk = false;
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-title);
|
||||
white-space: nowrap;
|
||||
margin-left: 0.25rem;
|
||||
|
||||
&.online:before {
|
||||
background-color: #94e185;
|
||||
border-color: #78d965;
|
||||
box-shadow: 0 0 5px 1px #94e185;
|
||||
}
|
||||
|
||||
&.offline:before {
|
||||
background-color: #c9404d;
|
||||
border-color: #c42c3b;
|
||||
box-shadow: 0 0 5px 1px #c9404d;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #000;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "UptimeKuma",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<Generic :item="item">
|
||||
<template #content>
|
||||
<p class="title is-4">{{ item.name }}</p>
|
||||
<p class="subtitle is-6">
|
||||
<template v-if="item.subtitle">
|
||||
{{ item.subtitle }}
|
||||
</template>
|
||||
<template v-else-if="versionstring">
|
||||
Version {{ versionstring }}
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
<template #indicator>
|
||||
<div v-if="status" class="status" :class="status">
|
||||
{{ status }}
|
||||
</div>
|
||||
</template>
|
||||
</Generic>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
|
||||
export default {
|
||||
name: "Vaultwarden",
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
},
|
||||
data: () => ({
|
||||
fetchOk: null,
|
||||
versionstring: null,
|
||||
}),
|
||||
computed: {
|
||||
status: function () {
|
||||
return this.fetchOk ? "online" : "offline";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchStatus();
|
||||
},
|
||||
methods: {
|
||||
fetchStatus: async function () {
|
||||
this.fetch("api/version")
|
||||
.then((response) => {
|
||||
this.fetchOk = true;
|
||||
this.versionstring = response;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.fetchOk = false;
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-title);
|
||||
white-space: nowrap;
|
||||
margin-left: 0.25rem;
|
||||
|
||||
&.online:before {
|
||||
background-color: #94e185;
|
||||
border-color: #78d965;
|
||||
box-shadow: 0 0 5px 1px #94e185;
|
||||
}
|
||||
|
||||
&.offline:before {
|
||||
background-color: #c9404d;
|
||||
border-color: #c42c3b;
|
||||
box-shadow: 0 0 5px 1px #c9404d;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #000;
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -22,13 +22,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "WUD",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -21,13 +21,9 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
|
||||
export default {
|
||||
name: "Wallabag",
|
||||
components: {
|
||||
Generic,
|
||||
},
|
||||
mixins: [service],
|
||||
props: {
|
||||
item: Object,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
<script>
|
||||
import service from "@/mixins/service.js";
|
||||
import Generic from "./Generic.vue";
|
||||
const units = ["B", "KB", "MB", "GB"];
|
||||
|
||||
// Take the rate in bytes and keep dividing it by 1k until the lowest
|
||||
|
@ -50,7 +49,6 @@ const displayRate = (rate) => {
|
|||
|
||||
export default {
|
||||
name: "QBittorrent",
|
||||
components: { Generic },
|
||||
mixins: [service],
|
||||
props: { item: Object },
|
||||
data: () => ({ dl: null, ul: null, count: null, error: null }),
|
||||
|
|
|
@ -3,9 +3,12 @@ import { createApp, h } from "vue";
|
|||
import App from "./App.vue";
|
||||
|
||||
const app = createApp(App);
|
||||
import Generic from "./components/services/Generic.vue";
|
||||
|
||||
app.component("DynamicStyle", (_props, context) => {
|
||||
return h("style", {}, context.slots);
|
||||
});
|
||||
app
|
||||
.component("Generic", Generic)
|
||||
.component("DynamicStyle", (_props, context) => {
|
||||
return h("style", {}, context.slots);
|
||||
});
|
||||
|
||||
app.mount("#app-mount");
|
||||
|
|
Loading…
Reference in New Issue