getumbrel / umbrel-dashboard

[Deprecated] Moved to https://github.com/getumbrel/umbrel/tree/master/packages/dashboard. Web-based dashboard to interact with your Umbrel.
https://github.com/getumbrel/umbrel/tree/master/packages/dashboard
Other
132 stars 69 forks source link

Discussion: Refactor raw SVG paths into maintainable and resusable component #370

Open TannerR1776 opened 3 years ago

TannerR1776 commented 3 years ago

I am opening this issue to discus the possibility of refactoring the raw SVG paths used throughout the front-end code into a reusable component. As it currently stands, there are places where these (long) paths are reused over and over again, creating additional lines of code that should not be required. Additionally, its hard to identify what these SVG icons are actually supposed to be displaying without either checking the context of the element, or checking the actual path itself. (there are probably vscode extensions for this, but I digress)

I am proposing that we convert these raw paths into a reusable component that will remove code duplication, and make the SVGs easier to work with. As part of this issue, I will be adding a WIP PR as an example of one solution to this problem that I think will help clean up this code, and make it easier to maintain. If there is interest, I will work on converting the remaining SVGs to use this new component.

Feedback welcome.

diazemiliano commented 2 years ago

Hi @TannerR1776 I would be happy to help with this, I solved it before with the following approach... Basically we have just one component importing all the SVG's and then also some custom rules for SVG imports in vue.config.js that allow us to process SVG's imports with SVGO. It can be done automatically resolving SVG's file names too, but for documentation, readability and maintainability sometimes is better to import each new SVG manually 😁. Also follows a convention for file naming that of course can be changed or omitted.

I can create a POC or explain deeply if you like.

// InlineSvgComponent.vue

<template>
  <component :is="'inline-svg-' + svgName" />
</template>

<script>
  import InlineSvgUmbrelLogo from "@/assets/umbrel-logo.svg?inline";
  import InlineSvgBitcoingLogo from "@/assets/bitcoin-logo.svg?inline";

  export default {
    name: "inline-svg",
    inheritAttrs: true,
    props: {
      svgName: {
        type: String,
        required: true,
      },
    },
  }
</script>
// vue.config.js

chainWebpack: (config) => {
// Allow load svg's inline.
const svgRule = config.module.rule("svg");
svgRule.uses.clear();
svgRule
  .oneOf("inline")
  .resourceQuery(/inline/)
  .use("babel-loader")
  .loader("babel-loader")
  .end()
  .use("vue-svg-loader")
  .loader("vue-svg-loader")
  .options({
    svgo: {
      plugins: [
        // Some custom options.
        { removeComments: true },
        { removeXMLNS: true },
        { removeStyleElement: true },
        { addClassesToSVGElement: { classNames: ["inline-svg"] }, },
      ],
    },
  })
  .end()
  .end();
}
// HeaderNavigation.vue

<template>
  ...
    <InlineSvg svgName="umbrel-logo" />
  ...
</template>