Skip to content

Commit

Permalink
feat: adding GroupedCard to improve style
Browse files Browse the repository at this point in the history
  • Loading branch information
Lebe1ge committed Dec 16, 2024
1 parent e0e95fc commit 13fc313
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 214 deletions.
321 changes: 177 additions & 144 deletions custom_components/linus_dashboard/www/linus-strategy.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions src/cards/GroupedCard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { AbstractCard } from "./AbstractCard";
import { EntityCardConfig } from "../types/lovelace-mushroom/cards/entity-card-config";
import { SwipeCard } from "./SwipeCard";
import { SwipeCardConfig } from "../types/lovelace-mushroom/cards/swipe-card-config";


// noinspection JSUnusedGlobalSymbols Class is dynamically imported.
/**
* Grouped Card Class
*
* Used to create a card for controlling an entity of the light domain.
*
* @class
* @extends AbstractCard
*/
class GroupedCard {

/**
* Configuration of the card.
*
* @type {AbstractCard}
*/
config: { cards: (AbstractCard | EntityCardConfig)[] } = {
cards: [],
};

/**
* Class constructor.
*
* @param {AbstractCard[]} cards The hass entity to create a card for.
* @throws {Error} If the Helper module isn't initialized.
*/
constructor(cards: (AbstractCard | EntityCardConfig)[]) {

this.config.cards = cards;
}

/**
* Get a card.
*
* @return {AbstractCard} A card object.
*/
getCard(): EntityCardConfig | SwipeCardConfig {

// Group entity cards into pairs and create vertical stacks
const groupedEntityCards = [];
for (let i = 0; i < this.config.cards.length; i += 2) {
groupedEntityCards.push({
type: "vertical-stack",
cards: this.config.cards.slice(i, i + 2),
});
}

// If there are more than 2 groups, use a GroupedCard, otherwise use a horizontal stack
const groupedCards = groupedEntityCards.length > 2
? new SwipeCard(groupedEntityCards).getCard()
: {
type: "horizontal-stack",
cards: groupedEntityCards,
}

return groupedCards;
}
}

export { GroupedCard };
12 changes: 5 additions & 7 deletions src/cards/SwipeCard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AbstractCard} from "./AbstractCard";
import { AbstractCard } from "./AbstractCard";
import { SwipeCardConfig } from "../types/lovelace-mushroom/cards/swipe-card-config";
import { SwiperOptions } from "swiper/types/swiper-options";
import { EntityCardConfig } from "../types/lovelace-mushroom/cards/entity-card-config";
Expand Down Expand Up @@ -39,14 +39,14 @@ class SwipeCard {
* @param {SwiperOptions} [options={}] Options for the card.
* @throws {Error} If the Helper module isn't initialized.
*/
constructor(cards: (AbstractCard | EntityCardConfig)[], options?: SwiperOptions) {
constructor(cards: (AbstractCard | EntityCardConfig)[], options?: SwiperOptions) {

this.config.cards = cards;

const multipleSlicesPerView = 2.2
const slidesPerView = cards.length > 2 ? multipleSlicesPerView : cards.length ?? 1

this.config.parameters = {...this.config.parameters, slidesPerView, ...options};
this.config.parameters = { ...this.config.parameters, slidesPerView, ...options };
}

/**
Expand All @@ -55,10 +55,8 @@ class SwipeCard {
* @return {SwipeCardConfig} A card object.
*/
getCard(): SwipeCardConfig {
return {
...this.config,
};
return this.config;
}
}

export {SwipeCard};
export { SwipeCard };
4 changes: 2 additions & 2 deletions src/views/AbstractView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { LovelaceCardConfig, LovelaceSectionConfig, LovelaceViewConfig } from ".
import { HassServiceTarget } from "home-assistant-js-websocket";
import { TemplateCardConfig } from '../types/lovelace-mushroom/cards/template-card-config';
import { ChipsCardConfig } from '../types/lovelace-mushroom/cards/chips-card';
import { SwipeCard } from '../cards/SwipeCard';
import { addLightGroupsToEntities, getAreaName, getFloorName, slugify } from '../utils';
import { views } from '../types/strategy/views';
import { GroupedCard } from '../cards/GroupedCard';

/**
* Abstract View Class.
Expand Down Expand Up @@ -126,7 +126,7 @@ abstract class AbstractView {
.map(entity => new cardModule[className](entity).getCard());

if (entityCards.length) {
const areaCards = entityCards.length > 2 ? [new SwipeCard(entityCards).getCard()] : entityCards;
const areaCards = [new GroupedCard(entityCards).getCard()]
const titleCardOptions = {
...Helper.strategyOptions.domains[this.#domain].controllerCardOptions,
subtitle: getAreaName(area),
Expand Down
9 changes: 4 additions & 5 deletions src/views/AreaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import { TemplateCardConfig } from "../types/lovelace-mushroom/cards/template-ca
import { LovelaceViewConfig } from "../types/homeassistant/data/lovelace";
import { generic } from "../types/strategy/generic";
import StrategyArea = generic.StrategyArea;
import { SwipeCard } from "../cards/SwipeCard";
import { EntityCardConfig } from "../types/lovelace-mushroom/cards/entity-card-config";
import { ControllerCard } from "../cards/ControllerCard";
import { HassServiceTarget } from "home-assistant-js-websocket";
import { ImageAreaCard } from "../cards/ImageAreaCard";
import { AGGREGATE_DOMAINS, AREA_EXPOSED_CHIPS, UNDISCLOSED } from "../variables";
import { LovelaceChipConfig } from "../types/lovelace-mushroom/utils/lovelace/chip/types";
import { AreaStateChip } from "../chips/AreaStateChip";
import { addLightGroupsToEntities, createChipsFromList, getDomainTranslationKey } from "../utils";
import { ResourceKeys } from "../types/homeassistant/data/frontend";
import { UnavailableChip } from "../chips/UnavailableChip";
import { GroupedCard } from "../cards/GroupedCard";


// noinspection JSUnusedGlobalSymbols Class is dynamically imported.
Expand Down Expand Up @@ -172,7 +171,7 @@ class AreaView {
});

if (entityCards.length) {
domainCards.push(...(entityCards.length > 2 ? [new SwipeCard(entityCards).getCard()] : entityCards));
domainCards.push(new GroupedCard(entityCards).getCard())
domainCards.unshift(...titleCard);
}

Expand Down Expand Up @@ -212,7 +211,7 @@ class AreaView {
})
.map(entity_id => new cardModule.MiscellaneousCard(Helper.entities[entity_id], Helper.strategyOptions.card_options?.[entity_id]).getCard());

const miscellaneousCards = miscellaneousEntityCards.length > 2 ? [new SwipeCard(miscellaneousEntityCards).getCard()] : miscellaneousEntityCards;
const miscellaneousCards = new GroupedCard(miscellaneousEntityCards).getCard()

const titleCard = {
type: "heading",
Expand All @@ -229,7 +228,7 @@ class AreaView {
viewSections.push({
type: "grid",
column_span: 1,
cards: [titleCard, ...miscellaneousCards],
cards: [titleCard, miscellaneousCards],
});
} catch (e) {
Helper.logError("An error occurred while creating the domain cards!", e);
Expand Down
42 changes: 2 additions & 40 deletions src/views/FloorView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import { TemplateCardConfig } from "../types/lovelace-mushroom/cards/template-ca
import { LovelaceCardConfig, LovelaceViewConfig } from "../types/homeassistant/data/lovelace";
import { generic } from "../types/strategy/generic";
import StrategyFloor = generic.StrategyFloor;
import { SwipeCard } from "../cards/SwipeCard";
import { EntityCardConfig } from "../types/lovelace-mushroom/cards/entity-card-config";
import { ControllerCard } from "../cards/ControllerCard";
import { HassServiceTarget } from "home-assistant-js-websocket";
import { AGGREGATE_DOMAINS, AREA_EXPOSED_CHIPS } from "../variables";
import { LovelaceChipConfig } from "../types/lovelace-mushroom/utils/lovelace/chip/types";
import { AreaStateChip } from "../chips/AreaStateChip";
import { addLightGroupsToEntities, createChipsFromList, getDomainTranslationKey } from "../utils";
import { GroupedCard } from "../cards/GroupedCard";


// noinspection JSUnusedGlobalSymbols Class is dynamically imported.
Expand Down Expand Up @@ -169,8 +168,7 @@ class FloorView {

const titleCard = new ControllerCard(titleCardOptions, domain, area.slug).createCard();

let areaCards;
areaCards = entityCards.length > 2 ? [new SwipeCard(entityCards).getCard()] : entityCards;
let areaCards = [new GroupedCard(entityCards).getCard()]
areaCards.unshift(...titleCard);

domainCards.push(...areaCards);
Expand Down Expand Up @@ -212,42 +210,6 @@ class FloorView {
viewSections.push(section);
}


// // Handle default domain if not hidden
// if (!Helper.strategyOptions.domains.default.hidden) {
// const areaDevices = area.devices.filter(device_id => Helper.devices[device_id].area_id === floor.area_id);
// const miscellaneousEntities = floor.entities.filter(entity_id => {
// const entity = Helper.entities[entity_id];
// const entityLinked = areaDevices.includes(entity.device_id ?? "null") || entity.area_id === floor.area_id;
// const entityUnhidden = entity.hidden_by === null && entity.disabled_by === null;
// const domainExposed = exposedDomainIds.includes(entity.entity_id.split(".", 1)[0]);

// return entityUnhidden && !domainExposed && entityLinked;
// });

// if (miscellaneousEntities.length) {
// try {
// const cardModule = await import("../cards/MiscellaneousCard");

// const swipeCard = miscellaneousEntities
// .filter(entity_id => {
// const entity = Helper.entities[entity_id];
// const cardOptions = Helper.strategyOptions.card_options?.[entity.entity_id];
// const deviceOptions = Helper.strategyOptions.card_options?.[entity.device_id ?? "null"];
// return !cardOptions?.hidden && !deviceOptions?.hidden && !(entity.entity_category === "config" && Helper.strategyOptions.domains["_"].hide_config_entities);
// })
// .map(entity_id => new cardModule.MiscellaneousCard(Helper.entities[entity_id], Helper.strategyOptions.card_options?.[entity_id]).getCard());

// viewSections.push({
// type: "grid",
// column_span: 1,
// cards: [new SwipeCard(swipeCard).getCard()],
// });
// } catch (e) {
// Helper.logError("An error occurred while creating the domain cards!", e);
// }
// }
// }
} catch (e) {
Helper.logError("An error occurred while creating the domain cards!", e);
}
Expand Down
17 changes: 12 additions & 5 deletions src/views/HomeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ class HomeView {
isFirstLoop = false;
}

const temperatureEntity = getMAEntity(floor.floor_id, "sensor", "temperature");
const temperature = floor.areas_slug.some(area_slug => {
const area = Helper.areas[area_slug];
return area.domains?.temperature;
});

if (floors.length > 1) {
floorSection.cards.push(
Expand All @@ -232,10 +235,14 @@ class HomeView {
type: "custom:mushroom-chips-card",
alignment: "end",
chips: [
new ConditionalChip(
[{ entity: temperatureEntity?.entity_id!, state_not: UNAVAILABLE }],
new AggregateChip({ device_class: "temperature", show_content: true, magic_device_id: floor.floor_id, area_slug: floor.areas_slug }).getChip()
).getChip(),
temperature &&
new AggregateChip({
device_class: "temperature",
show_content: true,
magic_device_id: floor.floor_id,
area_slug: floor.areas_slug,
tap_action: navigateTo('temperature')
}).getChip(),
],
card_mod: {
style: `
Expand Down
8 changes: 2 additions & 6 deletions src/views/SecurityView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { PersonCard } from "../cards/PersonCard";
import { BinarySensorCard } from "../cards/BinarySensorCard";
import { createChipsFromList, getAreaName, getFloorName, navigateTo } from "../utils";
import { HassServiceTarget } from "home-assistant-js-websocket";
import { SwipeCard } from "../cards/SwipeCard";
import { ControllerCard } from "../cards/ControllerCard";
import { views } from "../types/strategy/views";
import { ChipsCardConfig } from "../types/lovelace-mushroom/cards/chips-card";
import { TemplateCardConfig } from "../types/lovelace-mushroom/cards/template-card-config";
import { LovelaceChipConfig } from "../types/lovelace-mushroom/utils/lovelace/chip/types";
import { SECURITY_EXPOSED_CHIPS } from "../variables";
import { GroupedCard } from "../cards/GroupedCard";

/**
* Security View Class.
Expand Down Expand Up @@ -264,11 +264,7 @@ class SecurityView {
}

if (entityCards.length) {
if (entityCards.length > 2) {
areaCards.push(new SwipeCard(entityCards).getCard());
} else {
areaCards.push(...entityCards);
}
areaCards.push(new GroupedCard(entityCards).getCard())
}

// Vertical stack the area cards if it has entities.
Expand Down
6 changes: 2 additions & 4 deletions src/views/UnavailableView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { Helper } from "../Helper";
import { LovelaceGridCardConfig } from "../types/homeassistant/lovelace/cards/types";
import { LovelaceCardConfig, LovelaceSectionConfig, LovelaceViewConfig } from "../types/homeassistant/data/lovelace";
import { HassServiceTarget } from "home-assistant-js-websocket";

import { SwipeCard } from '../cards/SwipeCard';
import { getEntityDomain, getFloorName, slugify } from '../utils';
import { views } from '../types/strategy/views';
import { GroupedCard } from '../cards/GroupedCard';

/**
* Abstract View Class.
Expand Down Expand Up @@ -81,8 +80,7 @@ class UnavailableView {
.map(entity => new cardModule.MiscellaneousCard(entity).getCard());

if (entityCards.length) {
const areaCards = entityCards.length > 2 ? [new SwipeCard(entityCards).getCard()] : entityCards;
floorCards.push(...areaCards);
floorCards.push(new GroupedCard(entityCards).getCard())
}
}

Expand Down

0 comments on commit 13fc313

Please sign in to comment.