Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
brunosabot committed Aug 7, 2024
0 parents commit 5b881c4
Show file tree
Hide file tree
Showing 13 changed files with 1,033 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Validate

on:
push:
pull_request:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:

jobs:
validate-hacs:
runs-on: "ubuntu-latest"
steps:
- name: Code Checkout
uses: "actions/checkout@v4"
- name: Home Assistant Validation
uses: "home-assistant/actions/hassfest@master"
- name: HACS Validation
uses: "hacs/action@main"
with:
category: "plugin"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.env.*.local
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Bruno Sabot

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.
138 changes: 138 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Streamline Card

Streamline your Lovelace configuration with with a card template system.

This card is for [Lovelace](https://www.home-assistant.io/lovelace) on [Home Assistant](https://www.home-assistant.io/).

We all use multiple times the same block of configuration across our lovelace configuration and we don't want to change the same things in a hundred places across our configuration each time we want to modify something.

`streamline-card` to the rescue! This card allows you to reuse multiple times the same configuration in your lovelace configuration to avoid repetition and supports variables and default values.

`streamline-card` is an adaptation of `decluttering-card` by [@brunosabot](https://github.com/brunosabot) which is not maintained anymore.

## Installation

### With HACS (Recommended)

This method allows you to get updates directly on the HACS main page

1. If HACS is not installed yet, download it following the instructions on [https://hacs.xyz/docs/setup/download](https://hacs.xyz/docs/setup/download/)
2. Proceed to the HACS initial configuration following the instructions on [https://hacs.xyz/docs/configuration/basic](https://hacs.xyz/docs/configuration/basic)
3. On your sidebar go to `HACS` > `Frontend`
4. Click on the `+` button at the bottom right corner
5. Now search for `Streamline Card` and then click on the button at the bottom right corner to download it
6. Go back on your dashboard and click on the icon at the right top corner then on `Edit dashboard`
7. You can now click on `Add card` in the bottom right corner and search for `Streamline Card`

If it's not working, try to clear your browser cache.

### Without HACS

1. Download these files: [streamline-card.js](https://raw.githubusercontent.com/brunosabot/streamline-card/main/dist/streamline-card.js)
2. Add these files to your `<config>/www` folder
3. On your dashboard click on the icon at the right top corner then on `Edit dashboard`
4. Click again on that icon and then click on `Manage resources`
5. Click on `Add resource`
6. Copy and paste this: `/local/streamline-card.js?v=1`
7. Click on `JavaScript Module` then `Create`
8. Go back and refresh your page
9. You can now click on `Add card` in the bottom right corner and search for `streamline Card`
10. After any update of the file you will have to edit `/local/streamline-card.js?v=1` and change the version to any higher number

If it's not working, just try to clear your browser cache.`

## Configuration

### Defining your templates

First, you need to define your templates.

The templates are defined in an object at the root of your lovelace configuration. This object needs to be named `streamline_templates`.

This object needs to contains your templates declaration, each template has a name and can contain variables. A variable needs to be enclosed in double square brackets `[[variable_name]]`. It will later be replaced by a real value when you instantiate a card which uses this template. If a variable is alone on it's line, enclose it in single quotes: `'[[variable_name]]'`.

You can also define default values for your variables in the `default` object.

For a card:

```yaml
streamline_templates:
<template_name>
default: # This is optional
- <variable_name>: <variable_value>
- <variable_name>: <variable_value>
[...]
card: # This is where you put your card config (it can be a card embedding other cards)
type: custom:my-super-card
[...]
```

For a Picture-Element:

```yaml
streamline_templates:
<template_name>
default: # This is optional
- <variable_name>: <variable_value>
- <variable_name>: <variable_value>
[...]
element: # This is where you put your element config
type: icon
[...]
```

Example in your `lovelace-ui.yaml`:

```yaml
resources:
- url: /local/streamline-card.js
type: module

streamline_templates:
my_first_template: # This is the name of a template
default:
- icon: fire
card:
type: custom:button-card
name: "[[name]]"
icon: "mdi:[[icon]]"

my_second_template: # This is the name of another template
card:
type: custom:vertical-stack-in-card
cards:
- type: horizontal-stack
cards:
- type: custom:button-card
entity: "[[entity_1]]"
- type: custom:button-card
entity: "[[entity_2]]"
```
### Using the card
| Name | Type | Requirement | Description |
| --------- | ------ | ------------ | -------------------------------------------------------------- |
| type | string | **Required** | `custom:streamline-card` |
| template | object | **Required** | The template to use from `streamline_templates` |
| variables | list | **Optional** | List of variables and their value to replace in the `template` |

Example which references the previous templates:

```yaml
- type: custom:streamline-card
template: my_first_template
variables:
- name: Test Button
- icon: arrow-up
- type: custom:streamline-card
template: my_first_template
variables: Default Icon Button
- type: custom:streamline-card
template: my_second_template
variables:
- entity_1: switch.my_switch
- entity_2: light.my_light
```
124 changes: 124 additions & 0 deletions dist/streamline-card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
var l = Object.defineProperty;
var h = (e, a, s) => a in e ? l(e, a, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[a] = s;
var n = (e, a, s) => h(e, typeof a != "symbol" ? a + "" : a, s);
function u(e, a) {
if (!e && !a.default)
return a.card;
let s = [];
e && (s = e.slice(0)), a.default && (s = s.concat(a.default));
let i = a.card ? JSON.stringify(a.card) : JSON.stringify(a.element);
return s.forEach((t) => {
const r = Object.keys(t)[0], o = Object.values(t)[0];
if (typeof o == "number" || typeof o == "boolean") {
const d = new RegExp(`"\\[\\[${r}\\]\\]"`, "gm");
i = i.replace(d, o);
}
if (typeof o == "object") {
const d = new RegExp(`"\\[\\[${r}\\]\\]"`, "gm"), c = JSON.stringify(o);
i = i.replace(d, c);
} else {
const d = new RegExp(`\\[\\[${r}\\]\\]`, "gm");
i = i.replace(d, o);
}
}), JSON.parse(i);
}
function p() {
let e = document.querySelector("hc-main");
if (e = e && e.shadowRoot, e = e && e.querySelector("hc-lovelace"), e = e && e.shadowRoot, e = e && e.querySelector("hui-view"), e) {
const a = e.lovelace;
return a.current_view = e.___curView, a;
}
return null;
}
function f() {
let e = document.querySelector("home-assistant");
if (e = e && e.shadowRoot, e = e && e.querySelector("home-assistant-main"), e = e && e.shadowRoot, e = e && e.querySelector("app-drawer-layout partial-panel-resolver, ha-drawer partial-panel-resolver"), e = e && e.shadowRoot || e, e = e && e.querySelector("ha-panel-lovelace"), e = e && e.shadowRoot, e = e && e.querySelector("hui-root"), e) {
const a = e.lovelace;
return a.current_view = e.___curView, a;
}
return null;
}
const _ = "0.0.1";
(async function() {
const e = window.loadCardHelpers ? await window.loadCardHelpers() : void 0;
class a extends HTMLElement {
constructor() {
super();
n(this, "_editMode", !1);
n(this, "_isConnected", !1);
n(this, "_config", {});
n(this, "_hass", {});
n(this, "_card");
n(this, "_shadow");
n(this, "_accessedProperties", /* @__PURE__ */ new Set());
this._shadow = this.shadowRoot || this.attachShadow({ mode: "open" });
}
updateCardHass() {
this._isConnected && this._card && this._hass && (this._card.hass = this._hass);
}
updateCardEditMode() {
this._isConnected && this._card && (this._card.editMode = this._editMode);
}
updateCardConfig() {
var t, r;
this._isConnected && this._card && this._config.card && ((r = (t = this._card).setConfig) == null || r.call(t, this._config.card));
}
connectedCallback() {
this._isConnected = !0, this.updateCardConfig(), this.updateCardEditMode(), this.updateCardHass();
}
disconnectedCallback() {
this._isConnected = !1;
}
set editMode(t) {
t !== this._editMode && (this._editMode = t, this.updateCardEditMode());
}
set hass(t) {
this._hass = t, this.updateCardHass();
}
parseConfig(t) {
const r = f() || p();
if (!r.config && !r.config.streamline_templates)
throw new Error(
"The object streamline_templates doesn't exist in your main lovelace config."
);
const o = r.config.streamline_templates[this._config.template];
if (o)
if (o.card || o.element) {
if (o.card && o.element)
throw new Error("You can define a card and an element in the template");
} else throw new Error(
"You should define either a card or an element in the template"
);
else throw new Error(
`The template "${t.template}" doesn't exist in streamline_templates`
);
this._config = u(t.variables, o);
}
async setConfig(t) {
if (this._config = t, this.parseConfig(t), this._card === void 0) {
if (this._config.type === void 0)
throw new Error("[Streamline Card] You need to define a type");
this._card = e.createCardElement(this._config), this._shadow.appendChild(this._card);
}
this.updateCardConfig();
}
getCardSize() {
var t, r;
return ((r = (t = this._card) == null ? void 0 : t.getCardSize) == null ? void 0 : r.call(t)) ?? 1;
}
getLayoutOptions() {
var t, r;
return (r = (t = this._card) == null ? void 0 : t.getLayoutOptions) == null ? void 0 : r.call(t);
}
}
customElements.define("streamline-card", a), window.customCards = window.customCards || [], window.customCards.push({
type: "streamline-card",
name: "Streamline Card",
preview: !1,
description: "A config simplifier."
}), console.info(
`%c Streamline Card %c ${_}`,
"background-color:#c2b280;color:#242424;padding:4px 4px 4px 8px;border-radius:20px 0 0 20px;font-family:sans-serif;",
"background-color:#5297ff;color:#242424;padding:4px 8px 4px 4px;border-radius:0 20px 20px 0;font-family:sans-serif;"
);
})();
7 changes: 7 additions & 0 deletions hacs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Streamline Card",
"content_in_root": false,
"render_readme": true,
"filename": "streamline-card.js",
"homeassistant": "2023.9.0"
}
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "streamline-card",
"version": "0.0.1",
"description": "",
"type": "module",
"main": "src/streamline-card.js",
"scripts": {
"dev": "vite build --watch --mode development",
"build": "vite build",
"preview": "vite preview"
},
"author": "",
"license": "MIT",
"dependencies": {
"vite": "^5.3.5"
}
}
Loading

0 comments on commit 5b881c4

Please sign in to comment.