97 lines
2.7 KiB
TypeScript
97 lines
2.7 KiB
TypeScript
import { fireEvent } from './fire-event';
|
|
|
|
const SPECIAL_TYPES = new Set(['call-service', 'divider', 'section', 'weblink', 'cast', 'select']);
|
|
const DOMAIN_TO_ELEMENT_TYPE = {
|
|
alert: 'toggle',
|
|
automation: 'toggle',
|
|
climate: 'climate',
|
|
cover: 'cover',
|
|
fan: 'toggle',
|
|
group: 'group',
|
|
input_boolean: 'toggle',
|
|
input_number: 'input-number',
|
|
input_select: 'input-select',
|
|
input_text: 'input-text',
|
|
light: 'toggle',
|
|
lock: 'lock',
|
|
media_player: 'media-player',
|
|
remote: 'toggle',
|
|
scene: 'scene',
|
|
script: 'script',
|
|
sensor: 'sensor',
|
|
timer: 'timer',
|
|
switch: 'toggle',
|
|
vacuum: 'toggle',
|
|
// Temporary. Once climate is rewritten,
|
|
// water heater should get it's own row.
|
|
water_heater: 'climate',
|
|
input_datetime: 'input-datetime',
|
|
};
|
|
|
|
declare global {
|
|
// eslint-disable-next-line
|
|
interface HASSDomEvents {
|
|
'll-rebuild': Record<string, unknown>;
|
|
'll-badge-rebuild': Record<string, unknown>;
|
|
}
|
|
}
|
|
|
|
export const createThing = (cardConfig, isRow = false) => {
|
|
const _createError = (error, config) => {
|
|
return _createThing('hui-error-card', {
|
|
type: 'error',
|
|
error,
|
|
config,
|
|
});
|
|
};
|
|
|
|
const _createThing = (tag, config) => {
|
|
const element = window.document.createElement(tag);
|
|
try {
|
|
// Preventing an error-card infinity loop: https://github.com/custom-cards/custom-card-helpers/issues/54
|
|
if (!element.setConfig) return;
|
|
element.setConfig(config);
|
|
} catch (err) {
|
|
console.error(tag, err);
|
|
return _createError((err as Error).message, config);
|
|
}
|
|
return element;
|
|
};
|
|
|
|
if (!cardConfig || typeof cardConfig !== 'object' || (!isRow && !cardConfig.type))
|
|
return _createError('No type defined', cardConfig);
|
|
let tag = cardConfig.type;
|
|
if (tag && tag.startsWith('custom:')) {
|
|
tag = tag.substr('custom:'.length);
|
|
} else if (isRow) {
|
|
if (SPECIAL_TYPES.has(tag)) {
|
|
tag = `hui-${tag}-row`;
|
|
} else {
|
|
if (!cardConfig.entity) {
|
|
return _createError('Invalid config given.', cardConfig);
|
|
}
|
|
|
|
const domain = cardConfig.entity.split('.', 1)[0];
|
|
tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || 'text'}-entity-row`;
|
|
}
|
|
} else {
|
|
tag = `hui-${tag}-card`;
|
|
}
|
|
|
|
if (customElements.get(tag)) return _createThing(tag, cardConfig);
|
|
|
|
// If element doesn't exist (yet) create an error
|
|
const element = _createError(`Custom element doesn't exist: ${cardConfig.type}.`, cardConfig);
|
|
element.style.display = 'None';
|
|
const timer = setTimeout(() => {
|
|
element.style.display = '';
|
|
}, 2000);
|
|
// Remove error if element is defined later
|
|
customElements.whenDefined(cardConfig.type).then(() => {
|
|
clearTimeout(timer);
|
|
fireEvent(element, 'll-rebuild', {}, element);
|
|
});
|
|
|
|
return element;
|
|
};
|