From 1f3abbb1394f8f20e89934f7a042baed8dd5ddba Mon Sep 17 00:00:00 2001 From: Thomas Nairn Date: Fri, 30 Jul 2021 19:44:41 +0200 Subject: [PATCH] feat: Allow icons to be loaded externally --- README.md | 14 +++--- docker-compose.yml | 1 + docs/connectors/docker.md | 6 +-- docs/connectors/raw.md | 2 +- packages/agent/Dockerfile | 2 +- packages/core/.dockerignore | 3 +- .../client/components/DynamicIcon/index.tsx | 47 ++++++++++++++++--- .../core/client/components/Item/index.tsx | 12 ++--- packages/core/config.json | 4 +- packages/core/server/icon-handler/index.ts | 2 +- 10 files changed, 64 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 03b0714..430bcc5 100644 --- a/README.md +++ b/README.md @@ -116,12 +116,12 @@ config.json "category": "Other", "name": "Beer Tab", "state": "GREEN", - "icon": "@styled-icons/boxicons-regular/Beer" + "icon": "@svg-icons/boxicons-regular/Beer" }, { "name": "Beer Tab Dependency", "state": "GREEN", - "icon": "@styled-icons/ionicons-solid/Beer", + "icon": "@svg-icons/ionicons-solid/Beer", "parents": ["Beer Tab"] } ] @@ -157,8 +157,8 @@ You can use any icons available in [styled-icons](https://styled-icons.js.org/). Super simple, go to the page above, click the icon you would like to use, and use it in your config or docker labels. Example using docker labels: -`dockerDash.icon: '@styled-icons/simple-icons/Plex'` is to load the `Plex` icon in the [simple-icons](https://styled-icons.js.org/?s=plex) pack -`dockerDash.icon: '@styled-icons/simple-icons/Homeassistant'` is to load the `Homeassistant` icon in the [simple-icons pack](https://styled-icons.js.org/?s=home%20assistant) +`dockerDash.icon: '@svg-icons/simple-icons/Plex'` is to load the `Plex` icon in the [simple-icons](https://styled-icons.js.org/?s=plex) pack +`dockerDash.icon: '@svg-icons/simple-icons/Homeassistant'` is to load the `Homeassistant` icon in the [simple-icons pack](https://styled-icons.js.org/?s=home%20assistant) Example using config.json: @@ -170,7 +170,7 @@ Example using config.json: "containerMap": { "plugsy-container-name": { "category": "Home", - "icon": "@styled-icons/boxicons-regular/Crown", + "icon": "@svg-icons/boxicons-regular/Crown", "name": "Plugsy" } } @@ -203,12 +203,12 @@ Example using the [raw connector](docs/connectors/raw.md): "category": "Other", "name": "Beer Tab", "state": "GREEN", - "icon": "@styled-icons/boxicons-regular/Beer" + "icon": "@svg-icons/boxicons-regular/Beer" }, { "name": "Beer Tab Dependency", "state": "GREEN", - "icon": "@styled-icons/ionicons-solid/Beer", + "icon": "@svg-icons/ionicons-solid/Beer", "parents": ["Beer Tab"] } ] diff --git a/docker-compose.yml b/docker-compose.yml index ebbaec2..8fb60ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,7 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - .:/home/node/app + - ./packages/core/config.json:/config.json ports: - '3000:3000' diff --git a/docs/connectors/docker.md b/docs/connectors/docker.md index 93f1809..bfaa2a8 100644 --- a/docs/connectors/docker.md +++ b/docs/connectors/docker.md @@ -104,17 +104,17 @@ services: "vikunjafrontend": { "name": "Vikunja", "category": "Home", - "icon": "@styled-icons/bootstrap/Pencil", + "icon": "@svg-icons/bootstrap/Pencil", "link": "https://my.vikunja.com" }, "vikunjaapi": { "name": "API", - "icon": "@styled-icons/boxicons-regular/Server", + "icon": "@svg-icons/boxicons-regular/Server", "parents": ["Vikunja"] }, "vikunjadb": { "name": "DB", - "icon": "@styled-icons/fa-solid/Database", + "icon": "@svg-icons/fa-solid/Database", "parents": ["Vikunja"] } } diff --git a/docs/connectors/raw.md b/docs/connectors/raw.md index 54d5633..321b7fd 100644 --- a/docs/connectors/raw.md +++ b/docs/connectors/raw.md @@ -37,7 +37,7 @@ Provides items in the dashboard directly from the config itself { "name": "Home Assisant", "category": "My Category", // Optional, defaults to null - "icon": "@styled-icons/simple-icons/Homeassistant", // Optional, defaults to null + "icon": "@svg-icons/simple-icons/Homeassistant", // Optional, defaults to null "link": "https://my.home-assistant.io/", // Optional, defaults to null "state": "GREY", // Optional, defaults to null. Valid options: "RED" | "GREEN" | "YELLOW" | "GREY" "status": "", //Optional, defaults to null. Status text will appear under the item in the dashboard diff --git a/packages/agent/Dockerfile b/packages/agent/Dockerfile index 8855b07..6a2a62e 100644 --- a/packages/agent/Dockerfile +++ b/packages/agent/Dockerfile @@ -21,7 +21,7 @@ WORKDIR /opt/demo ## COPY ${BUILD_DIR}/package.json ${BUILD_DIR}/ -COPY package.json yarn.lock .yarnrc.yml .pnp.js codegen.yml tsconfig.base.json . +COPY package.json yarn.lock .yarnrc.yml .pnp.js codegen.yml tsconfig.base.json ./ COPY .yarn/ /opt/demo/.yarn/ ## diff --git a/packages/core/.dockerignore b/packages/core/.dockerignore index ea9a3cb..c7762c5 100644 --- a/packages/core/.dockerignore +++ b/packages/core/.dockerignore @@ -10,4 +10,5 @@ node_modules dist *generated* .github -README.md \ No newline at end of file +README.md +config.json \ No newline at end of file diff --git a/packages/core/client/components/DynamicIcon/index.tsx b/packages/core/client/components/DynamicIcon/index.tsx index f896684..0e126ab 100644 --- a/packages/core/client/components/DynamicIcon/index.tsx +++ b/packages/core/client/components/DynamicIcon/index.tsx @@ -1,11 +1,32 @@ import SVG, { Props as SVGProps } from "react-inlinesvg"; +// We're using react-inlinesvg as the SVGs coming from '@svg-icons' is broken -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; -export interface DynamicIconProps extends Omit { +export interface DynamicIconProps extends Omit { icon: string; } +export const DynamicImage: React.FC< + DynamicIconProps & { onError: () => void } +> = ({ icon, onError, width, height }) => { + return ; +}; + +export const DynamicSVG: React.FC void }> = + ({ icon, width, height, onError, ...props }) => { + return ( + } + onError={onError} + {...props} + /> + ); + }; + export const DynamicIcon: React.FC = ({ icon, width, @@ -14,21 +35,33 @@ export const DynamicIcon: React.FC = ({ }) => { const [error, setError] = useState(false); useEffect(() => setError(false), [icon]); + const onError = useCallback(() => setError(true), []); + const Component = useMemo( + () => + icon.startsWith("http") && !icon.endsWith(".svg") + ? DynamicImage + : DynamicSVG, + [icon] + ); return !error ? ( - } - onError={() => setError(true)} + onError={onError} {...props} /> ) : ( } + onError={() => + console.error( + "Unable to load @svg-icons/fluentui-system-regular/DocumentError icon" + ) + } {...props} /> ); diff --git a/packages/core/client/components/Item/index.tsx b/packages/core/client/components/Item/index.tsx index 4f55a87..6d6de40 100644 --- a/packages/core/client/components/Item/index.tsx +++ b/packages/core/client/components/Item/index.tsx @@ -209,12 +209,12 @@ export const Item: React.FC = ({ const ConnectorIcon = useMemo( () => connectorType === "DOCKER" - ? staticIcon("@styled-icons/ionicons-solid/LogoDocker") + ? staticIcon("@svg-icons/ionicons-solid/LogoDocker") : connectorType === "RAW" - ? staticIcon("@styled-icons/simple-icons/Visualstudiocode") + ? staticIcon("@svg-icons/simple-icons/Visualstudiocode") : connectorType === "WEBSITE" - ? staticIcon("@styled-icons/bootstrap/Globe") - : staticIcon("@styled-icons/bootstrap/QuestionCircle"), + ? staticIcon("@svg-icons/bootstrap/Globe") + : staticIcon("@svg-icons/bootstrap/QuestionCircle"), [connectorType] ); const theme = useTheme() as Theme; @@ -262,7 +262,7 @@ export const Item: React.FC = ({ {link ? ( @@ -271,7 +271,7 @@ export const Item: React.FC = ({ ) : null} diff --git a/packages/core/config.json b/packages/core/config.json index ab4d794..bdc7494 100644 --- a/packages/core/config.json +++ b/packages/core/config.json @@ -15,7 +15,7 @@ "type": "DOCKER", "config": { "containerMap": { - "plugsy": { + "dockerdash-core": { "category": "Home", "icon": "@styled-icons/boxicons-regular/Crown", "name": "Plugsy" @@ -32,7 +32,7 @@ "display": { "name": "Home Assistant", "category": "Home", - "icon": "@styled-icons/simple-icons/Plex", + "icon": "https://github.com/ground7/unraid-animated-svgs/blob/master/Always%20Animate/downloads.svg", "link": "https://my.homeassistant.com" } }, diff --git a/packages/core/server/icon-handler/index.ts b/packages/core/server/icon-handler/index.ts index 3b792e5..a476ccb 100644 --- a/packages/core/server/icon-handler/index.ts +++ b/packages/core/server/icon-handler/index.ts @@ -1,7 +1,7 @@ import { readFileSync } from "fs"; import { Handler } from "express"; import { paramCase } from "change-case"; -const EXAMPLES = ["@styled-icons/simple-icons/Plex"]; +const EXAMPLES = ["@svg-icons/simple-icons/Plex"]; export const svgIconHandler: Handler = (req, res) => { const { iconPath } = req.params;