Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 299 additions & 0 deletions gallery/src/demos/demo-integration-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
import {
customElement,
html,
css,
internalProperty,
LitElement,
TemplateResult,
property,
} from "lit-element";
import "../../../src/components/ha-formfield";
import "../../../src/components/ha-switch";

import { IntegrationManifest } from "../../../src/data/integration";

import { provideHass } from "../../../src/fake_data/provide_hass";
import { HomeAssistant } from "../../../src/types";
import "../../../src/panels/config/integrations/ha-integration-card";
import "../../../src/panels/config/integrations/ha-ignored-config-entry-card";
import "../../../src/panels/config/integrations/ha-config-flow-card";
import type {
ConfigEntryExtended,
DataEntryFlowProgressExtended,
} from "../../../src/panels/config/integrations/ha-config-integrations";
import { DeviceRegistryEntry } from "../../../src/data/device_registry";
import { EntityRegistryEntry } from "../../../src/data/entity_registry";
import { classMap } from "lit-html/directives/class-map";

const createConfigEntry = (
title: string,
override: Partial<ConfigEntryExtended> = {}
): ConfigEntryExtended => ({
entry_id: title,
domain: "esphome",
localized_domain_name: "ESPHome",
title,
source: "zeroconf",
state: "loaded",
connection_class: "local_push",
supports_options: false,
supports_unload: true,
disabled_by: null,
...override,
});

const createManifest = (
isCustom: boolean,
isCloud: boolean
): IntegrationManifest => ({
name: "ESPHome",
domain: "esphome",
is_built_in: !isCustom,
config_flow: false,
documentation: "https://www.home-assistant.io/integrations/esphome/",
iot_class: isCloud ? "cloud_polling" : "local_polling",
});

const loadedEntry = createConfigEntry("Loaded");
const nameAsDomainEntry = createConfigEntry("ESPHome");
const longNameEntry = createConfigEntry(
"Entry with a super long name that is going to the next line"
);
const configPanelEntry = createConfigEntry("Config Panel", {
domain: "mqtt",
localized_domain_name: "MQTT",
});
const optionsFlowEntry = createConfigEntry("Options Flow", {
supports_options: true,
});
const setupErrorEntry = createConfigEntry("Setup Error", {
state: "setup_error",
});
const migrationErrorEntry = createConfigEntry("Migration Error", {
state: "migration_error",
});
const setupRetryEntry = createConfigEntry("Setup Retry", {
state: "setup_retry",
});
const failedUnloadEntry = createConfigEntry("Failed Unload", {
state: "failed_unload",
});
const notLoadedEntry = createConfigEntry("Not Loaded", { state: "not_loaded" });
const disabledEntry = createConfigEntry("Disabled", {
state: "not_loaded",
disabled_by: "user",
});
const disabledFailedUnloadEntry = createConfigEntry(
"Disabled - Failed Unload",
{
state: "failed_unload",
disabled_by: "user",
}
);

const configFlows: DataEntryFlowProgressExtended[] = [
{
flow_id: "adbb401329d8439ebb78ef29837826a8",
handler: "roku",
context: {
source: "ssdp",
unique_id: "YF008D862864",
title_placeholders: {
name: "Living room Roku",
},
},
step_id: "discovery_confirm",
localized_title: "Roku: Living room Roku",
},
{
flow_id: "adbb401329d8439ebb78ef29837826a8",
handler: "hue",
context: {
source: "reauth",
unique_id: "YF008D862864",
title_placeholders: {
name: "Living room Roku",
},
},
step_id: "discovery_confirm",
localized_title: "Philips Hue",
},
];

const configEntries: Array<{
items: ConfigEntryExtended[];
is_custom?: boolean;
disabled?: boolean;
highlight?: string;
}> = [
{ items: [loadedEntry] },
{ items: [configPanelEntry] },
{ items: [optionsFlowEntry] },
{ items: [nameAsDomainEntry] },
{ items: [longNameEntry] },
{ items: [setupErrorEntry] },
{ items: [migrationErrorEntry] },
{ items: [setupRetryEntry] },
{ items: [failedUnloadEntry] },
{ items: [notLoadedEntry] },
{
items: [
loadedEntry,
longNameEntry,
setupErrorEntry,
migrationErrorEntry,
setupRetryEntry,
failedUnloadEntry,
notLoadedEntry,
disabledEntry,
nameAsDomainEntry,
configPanelEntry,
optionsFlowEntry,
],
},
{ disabled: true, items: [disabledEntry] },
{ disabled: true, items: [disabledFailedUnloadEntry] },
{
disabled: true,
items: [disabledEntry, disabledFailedUnloadEntry],
},
{
items: [loadedEntry, configPanelEntry],
highlight: "Loaded",
},
];

const createEntityRegistryEntries = (
item: ConfigEntryExtended
): EntityRegistryEntry[] => [
{
config_entry_id: item.entry_id,
device_id: "mock-device-id",
area_id: null,
disabled_by: null,
entity_id: "binary_sensor.updater",
name: null,
icon: null,
platform: "updater",
},
];

const createDeviceRegistryEntries = (
item: ConfigEntryExtended
): DeviceRegistryEntry[] => [
{
entry_type: null,
config_entries: [item.entry_id],
connections: [],
manufacturer: "ESPHome",
model: "Mock Device",
name: "Tag Reader",
sw_version: null,
id: "mock-device-id",
identifiers: [],
via_device_id: null,
area_id: null,
name_by_user: null,
disabled_by: null,
},
];

@customElement("demo-integration-card")
export class DemoIntegrationCard extends LitElement {
@property({ attribute: false }) hass?: HomeAssistant;

@internalProperty() isCustomIntegration = false;

@internalProperty() isCloud = false;

protected render(): TemplateResult {
if (!this.hass) {
return html``;
}
return html`
<div class="filters">
<ha-formfield label="Custom Integration">
<ha-switch @change=${this._toggleCustomIntegration}></ha-switch>
</ha-formfield>
<ha-formfield label="Relies on cloud">
<ha-switch @change=${this._toggleCloud}></ha-switch>
</ha-formfield>
</div>

<ha-ignored-config-entry-card
.hass=${this.hass}
.entry=${createConfigEntry("Ignored Entry")}
.manifest=${createManifest(this.isCustomIntegration, this.isCloud)}
></ha-ignored-config-entry-card>

${configFlows.map(
(flow) => html`
<ha-config-flow-card
.hass=${this.hass}
.flow=${flow}
.manifest=${createManifest(this.isCustomIntegration, this.isCloud)}
></ha-config-flow-card>
`
)}
${configEntries.map(
(info) => html`
<ha-integration-card
class=${classMap({
highlight: info.highlight !== undefined,
})}
.hass=${this.hass}
domain="esphome"
.items=${info.items}
.manifest=${createManifest(this.isCustomIntegration, this.isCloud)}
.entityRegistryEntries=${createEntityRegistryEntries(info.items[0])}
.deviceRegistryEntries=${createDeviceRegistryEntries(info.items[0])}
?disabled=${info.disabled}
.selectedConfigEntryId=${info.highlight}
></ha-integration-card>
`
)}
`;
}

protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
const hass = provideHass(this);
hass.updateTranslations(null, "en");
hass.updateTranslations("config", "en");
}

private _toggleCustomIntegration() {
this.isCustomIntegration = !this.isCustomIntegration;
}

private _toggleCloud() {
this.isCloud = !this.isCloud;
}

static get styles() {
return css`
:host {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 16px 16px;
padding: 8px 16px 16px;
margin-bottom: 64px;
}

:host > * {
max-width: 500px;
}

ha-formfield {
margin: 8px 0;
display: block;
}
`;
}
}

declare global {
interface HTMLElementTagNameMap {
"demo-integration-card": DemoIntegrationCard;
}
}
10 changes: 8 additions & 2 deletions src/data/config_entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ export interface ConfigEntry {
domain: string;
title: string;
source: string;
state: string;
state:
| "loaded"
| "setup_error"
| "migration_error"
| "setup_retry"
| "not_loaded"
| "failed_unload";
connection_class: string;
supports_options: boolean;
supports_unload: boolean;
disabled_by: string | null;
disabled_by: "user" | null;
}

export interface ConfigEntryMutableParams {
Expand Down
14 changes: 7 additions & 7 deletions src/data/device_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export interface DeviceRegistryEntry {
config_entries: string[];
connections: Array<[string, string]>;
identifiers: Array<[string, string]>;
manufacturer: string;
model?: string;
name?: string;
sw_version?: string;
via_device_id?: string;
area_id?: string;
name_by_user?: string;
manufacturer: string | null;
model: string | null;
name: string | null;
sw_version: string | null;
via_device_id: string | null;
area_id: string | null;
name_by_user: string | null;
entry_type: "service" | null;
disabled_by: string | null;
}
Expand Down
10 changes: 5 additions & 5 deletions src/data/entity_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { HomeAssistant } from "../types";

export interface EntityRegistryEntry {
entity_id: string;
name: string;
icon?: string;
name: string | null;
icon: string | null;
platform: string;
config_entry_id?: string;
device_id?: string;
area_id?: string;
config_entry_id: string | null;
device_id: string | null;
area_id: string | null;
disabled_by: string | null;
}

Expand Down
8 changes: 7 additions & 1 deletion src/data/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export interface IntegrationManifest {
ssdp?: Array<{ manufacturer?: string; modelName?: string; st?: string }>;
zeroconf?: string[];
homekit?: { models: string[] };
quality_scale?: string;
quality_scale?: "gold" | "internal" | "platinum" | "silver";
iot_class:
| "assumed_state"
| "cloud_polling"
| "cloud_push"
| "local_polling"
| "local_push";
}

export const integrationIssuesUrl = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class DialogDeviceRegistryDetail extends LitElement {

@internalProperty() private _params?: DeviceRegistryDetailDialogParams;

@internalProperty() private _areaId?: string;
@internalProperty() private _areaId?: string | null;

@internalProperty() private _disabledBy!: string | null;

Expand Down
2 changes: 1 addition & 1 deletion src/panels/config/entities/entity-registry-basic-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {

@internalProperty() private _entityId!: string;

@internalProperty() private _areaId?: string;
@internalProperty() private _areaId?: string | null;

@internalProperty() private _disabledBy!: string | null;

Expand Down
Loading