forked from DigiLive/mushroom-strategy
- Make use of the debug module. - Make use of the auxiliaries module. - Make use of the localization module. - Make use of the Registry module. - Align code across the chip modules. - Make configurations immutable. - Make use of the refactored types.
160 lines
5.7 KiB
TypeScript
160 lines
5.7 KiB
TypeScript
import { HassServiceTarget } from 'home-assistant-js-websocket';
|
|
import HeaderCard from '../cards/HeaderCard';
|
|
import { Registry } from '../Registry';
|
|
import { LovelaceCardConfig } from '../types/homeassistant/data/lovelace/config/card';
|
|
import { LovelaceViewConfig } from '../types/homeassistant/data/lovelace/config/view';
|
|
import { StackCardConfig } from '../types/homeassistant/panels/lovelace/cards/types';
|
|
import { AbstractCardConfig, CustomHeaderCardConfig, StrategyHeaderCardConfig } from '../types/strategy/strategy-cards';
|
|
import { SupportedDomains } from '../types/strategy/strategy-generics';
|
|
import { ViewConfig, ViewConstructor } from '../types/strategy/strategy-views';
|
|
import { sanitizeClassName } from '../utilities/auxiliaries';
|
|
import { logMessage, lvlFatal } from '../utilities/debug';
|
|
import RegistryFilter from '../utilities/RegistryFilter';
|
|
|
|
/**
|
|
* Abstract View Class.
|
|
*
|
|
* To create a view configuration, this class should be extended by a child class.
|
|
* Child classes should override the default configuration so the view correctly reflects the entities of a domain.
|
|
*
|
|
* @remarks
|
|
* Before this class can be used, the Registry module must be initialized by calling {@link Registry.initialize}.
|
|
*/
|
|
abstract class AbstractView {
|
|
/** The base configuration of a view. */
|
|
protected baseConfiguration: LovelaceViewConfig = {
|
|
icon: 'mdi:view-dashboard',
|
|
subview: false,
|
|
};
|
|
|
|
/** A card configuration to control all entities in the view. */
|
|
private viewHeaderCardConfiguration: StackCardConfig = {
|
|
cards: [],
|
|
type: '',
|
|
};
|
|
|
|
protected get domain(): SupportedDomains | 'home' {
|
|
return (this.constructor as unknown as ViewConstructor).domain;
|
|
}
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* @remarks
|
|
* Before this class can be used, the Registry module must be initialized by calling {@link Registry.initialize}.
|
|
*/
|
|
protected constructor() {
|
|
if (!Registry.initialized) {
|
|
logMessage(lvlFatal, 'Registry not initialized!');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create the configuration of the cards to include in the view.
|
|
*/
|
|
protected async createCardConfigurations(): Promise<LovelaceCardConfig[]> {
|
|
if (this.domain === 'home') {
|
|
// The home domain should override this method because it hasn't entities of its own.
|
|
// The method override creates its own configurations for cards to show at the home view.
|
|
|
|
return [];
|
|
}
|
|
|
|
const viewCards: LovelaceCardConfig[] = [];
|
|
const domainEntities = new RegistryFilter(Registry.entities).whereDomain(this.domain).toList();
|
|
const moduleName = sanitizeClassName(this.domain + 'Card');
|
|
const DomainCard = (await import(`../cards/${moduleName}`)).default;
|
|
|
|
// Create card configurations for each area.
|
|
for (const area of Registry.areas) {
|
|
const areaCards: AbstractCardConfig[] = [];
|
|
|
|
// Set the target of the Header card to the current area.
|
|
let target: HassServiceTarget = {
|
|
area_id: [area.area_id],
|
|
};
|
|
const areaEntities = new RegistryFilter(domainEntities).whereAreaId(area.area_id).toList();
|
|
|
|
// Set the target of the Header card to entities without an area.
|
|
if (area.area_id === 'undisclosed') {
|
|
target = {
|
|
entity_id: areaEntities.map((entity) => entity.entity_id),
|
|
};
|
|
}
|
|
|
|
// Create a card configuration for each entity in the current area.
|
|
areaCards.push(
|
|
...areaEntities.map((entity) =>
|
|
new DomainCard(entity, Registry.strategyOptions.card_options?.[entity.entity_id]).getCard(),
|
|
),
|
|
);
|
|
|
|
// Vertically stack the cards of the current area.
|
|
if (areaCards.length) {
|
|
const areaHeaderCardOptions = (
|
|
'headerCardConfiguration' in this.baseConfiguration ? this.baseConfiguration.headerCardConfiguration : {}
|
|
) as CustomHeaderCardConfig;
|
|
|
|
// Create and insert a Header card.
|
|
areaCards.unshift(new HeaderCard(target, { title: area.name, ...areaHeaderCardOptions }).createCard());
|
|
|
|
viewCards.push({ type: 'vertical-stack', cards: areaCards });
|
|
}
|
|
}
|
|
|
|
// Add a Header Card to control all the entities in the view.
|
|
if (this.viewHeaderCardConfiguration.cards.length && viewCards.length) {
|
|
viewCards.unshift(this.viewHeaderCardConfiguration);
|
|
}
|
|
|
|
return viewCards;
|
|
}
|
|
|
|
/**
|
|
* Get a view configuration.
|
|
*
|
|
* The configuration includes the card configurations which are created by createCardConfigurations().
|
|
*/
|
|
async getView(): Promise<LovelaceViewConfig> {
|
|
return {
|
|
...this.baseConfiguration,
|
|
cards: await this.createCardConfigurations(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get the domain's entity ids to target for a HASS service call.
|
|
*/
|
|
private getDomainTargets(): HassServiceTarget {
|
|
return {
|
|
entity_id: Registry.entities
|
|
.filter((entity) => entity.entity_id.startsWith(this.domain + '.'))
|
|
.map((entity) => entity.entity_id),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Initialize the view configuration with defaults and custom settings.
|
|
*
|
|
* @param viewConfiguration The view's default configuration for the view.
|
|
* @param customConfiguration The view's custom configuration to apply.
|
|
* @param headerCardConfig The view's Header card configuration.
|
|
*/
|
|
protected initializeViewConfig(
|
|
viewConfiguration: ViewConfig,
|
|
customConfiguration: ViewConfig = {},
|
|
headerCardConfig: CustomHeaderCardConfig,
|
|
): void {
|
|
this.baseConfiguration = { ...this.baseConfiguration, ...viewConfiguration, ...customConfiguration };
|
|
|
|
this.viewHeaderCardConfiguration = new HeaderCard(this.getDomainTargets(), {
|
|
...(('headerCardConfiguration' in this.baseConfiguration
|
|
? this.baseConfiguration.headerCardConfiguration
|
|
: {}) as StrategyHeaderCardConfig),
|
|
...headerCardConfig,
|
|
}).createCard();
|
|
}
|
|
}
|
|
|
|
export default AbstractView;
|