Skip to content

Commit

Permalink
Add base support for sub entries (#23160)
Browse files Browse the repository at this point in the history
* Add base support for sub entries

* add demo types

* fix translations

* Use sub entry name when deleting

* Update show-dialog-sub-config-flow.ts

* adjust for multiple sub types

* WIP, not functional

* add subentry_type

* rename to supported_subentry_types

* config_subentries -> config_entries_subentries

* Add localized sub flow title

* use Record

* rename

* more rename
  • Loading branch information
bramkragten authored Feb 10, 2025
1 parent 03a415b commit 0d97afb
Show file tree
Hide file tree
Showing 20 changed files with 880 additions and 248 deletions.
2 changes: 2 additions & 0 deletions demo/src/ha-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class HaDemo extends HomeAssistantAppEl {
mockEntityRegistry(hass, [
{
config_entry_id: "co2signal",
config_subentry_id: null,
device_id: "co2signal",
area_id: null,
disabled_by: null,
Expand All @@ -85,6 +86,7 @@ export class HaDemo extends HomeAssistantAppEl {
},
{
config_entry_id: "co2signal",
config_subentry_id: null,
device_id: "co2signal",
area_id: null,
disabled_by: null,
Expand Down
1 change: 1 addition & 0 deletions demo/src/stubs/config_entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const mockConfigEntries = (hass: MockHomeAssistant) => {
supports_remove_device: false,
supports_unload: true,
supports_reconfigure: true,
supported_subentry_types: {},
pref_disable_new_entities: false,
pref_disable_polling: false,
disabled_by: null,
Expand Down
3 changes: 3 additions & 0 deletions gallery/src/pages/components/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: "bedroom",
configuration_url: null,
config_entries: ["config_entry_1"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand All @@ -71,6 +72,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: "backyard",
configuration_url: null,
config_entries: ["config_entry_2"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand All @@ -94,6 +96,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: null,
configuration_url: null,
config_entries: ["config_entry_3"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand Down
3 changes: 3 additions & 0 deletions gallery/src/pages/components/ha-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: "bedroom",
configuration_url: null,
config_entries: ["config_entry_1"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand All @@ -70,6 +71,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: "backyard",
configuration_url: null,
config_entries: ["config_entry_2"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand All @@ -93,6 +95,7 @@ const DEVICES: DeviceRegistryEntry[] = [
area_id: null,
configuration_url: null,
config_entries: ["config_entry_3"],
config_entries_subentries: {},
connections: [],
disabled_by: null,
entry_type: null,
Expand Down
4 changes: 4 additions & 0 deletions gallery/src/pages/misc/integration-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const createConfigEntry = (
supports_remove_device: false,
supports_unload: true,
supports_reconfigure: true,
supported_subentry_types: {},
num_subentries: 0,
disabled_by: null,
pref_disable_new_entities: false,
pref_disable_polling: false,
Expand Down Expand Up @@ -188,6 +190,7 @@ const createEntityRegistryEntries = (
): EntityRegistryEntry[] => [
{
config_entry_id: item.entry_id,
config_subentry_id: null,
device_id: "mock-device-id",
area_id: null,
disabled_by: null,
Expand All @@ -214,6 +217,7 @@ const createDeviceRegistryEntries = (
{
entry_type: null,
config_entries: [item.entry_id],
config_entries_subentries: {},
connections: [],
manufacturer: "ESPHome",
model: "Mock Device",
Expand Down
26 changes: 26 additions & 0 deletions src/data/config_entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface ConfigEntry {
supports_remove_device: boolean;
supports_unload: boolean;
supports_reconfigure: boolean;
supported_subentry_types: Record<string, { supports_reconfigure: boolean }>;
num_subentries: number;
pref_disable_new_entities: boolean;
pref_disable_polling: boolean;
disabled_by: "user" | null;
Expand All @@ -27,6 +29,30 @@ export interface ConfigEntry {
error_reason_translation_placeholders: Record<string, string> | null;
}

export interface SubEntry {
subentry_id: string;
subentry_type: string;
title: string;
unique_id: string;
}

export const getSubEntries = (hass: HomeAssistant, entry_id: string) =>
hass.callWS<SubEntry[]>({
type: "config_entries/subentries/list",
entry_id,
});

export const deleteSubEntry = (
hass: HomeAssistant,
entry_id: string,
subentry_id: string
) =>
hass.callWS({
type: "config_entries/subentries/delete",
entry_id,
subentry_id,
});

export type ConfigEntryMutableParams = Partial<
Pick<
ConfigEntry,
Expand Down
6 changes: 5 additions & 1 deletion src/data/data_entry_flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import type { Connection } from "home-assistant-js-websocket";
import type { HaFormSchema } from "../components/ha-form/types";
import type { ConfigEntry } from "./config_entries";

export type FlowType = "config_flow" | "options_flow" | "repair_flow";
export type FlowType =
| "config_flow"
| "config_subentries_flow"
| "options_flow"
| "repair_flow";

export interface DataEntryFlowProgressedEvent {
type: "data_entry_flow_progressed";
Expand Down
1 change: 1 addition & 0 deletions src/data/device_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
export interface DeviceRegistryEntry extends RegistryEntry {
id: string;
config_entries: string[];
config_entries_subentries: Record<string, (string | null)[]>;
connections: [string, string][];
identifiers: [string, string][];
manufacturer: string | null;
Expand Down
1 change: 1 addition & 0 deletions src/data/entity_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface EntityRegistryEntry extends RegistryEntry {
icon: string | null;
platform: string;
config_entry_id: string | null;
config_subentry_id: string | null;
device_id: string | null;
area_id: string | null;
labels: string[];
Expand Down
46 changes: 46 additions & 0 deletions src/data/sub_config_flow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { HomeAssistant } from "../types";
import type { DataEntryFlowStep } from "./data_entry_flow";

const HEADERS = {
"HA-Frontend-Base": `${location.protocol}//${location.host}`,
};

export const createSubConfigFlow = (
hass: HomeAssistant,
configEntryId: string,
subFlowType: string,
subentry_id?: string
) =>
hass.callApi<DataEntryFlowStep>(
"POST",
"config/config_entries/subentries/flow",
{
handler: [configEntryId, subFlowType],
show_advanced_options: Boolean(hass.userData?.showAdvanced),
subentry_id,
},
HEADERS
);

export const fetchSubConfigFlow = (hass: HomeAssistant, flowId: string) =>
hass.callApi<DataEntryFlowStep>(
"GET",
`config/config_entries/subentries/flow/${flowId}`,
undefined,
HEADERS
);

export const handleSubConfigFlowStep = (
hass: HomeAssistant,
flowId: string,
data: Record<string, any>
) =>
hass.callApi<DataEntryFlowStep>(
"POST",
`config/config_entries/subentries/flow/${flowId}`,
data,
HEADERS
);

export const deleteSubConfigFlow = (hass: HomeAssistant, flowId: string) =>
hass.callApi("DELETE", `config/config_entries/subentries/flow/${flowId}`);
1 change: 1 addition & 0 deletions src/data/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type TranslationCategory =
| "entity_component"
| "exceptions"
| "config"
| "config_subentries"
| "config_panel"
| "options"
| "device_automation"
Expand Down
2 changes: 1 addition & 1 deletion src/dialogs/config-flow/previews/flow-preview-generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class FlowPreviewGeneric extends LitElement {
(await this._unsub)();
this._unsub = undefined;
}
if (this.flowType === "repair_flow") {
if (this.flowType !== "config_flow" && this.flowType !== "options_flow") {
return;
}
try {
Expand Down
2 changes: 1 addition & 1 deletion src/dialogs/config-flow/previews/flow-preview-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class FlowPreviewTemplate extends LitElement {
(await this._unsub)();
this._unsub = undefined;
}
if (this.flowType === "repair_flow") {
if (this.flowType !== "config_flow" && this.flowType !== "options_flow") {
return;
}
try {
Expand Down
4 changes: 3 additions & 1 deletion src/dialogs/config-flow/show-dialog-config-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export const loadConfigFlowDialog = loadDataEntryFlowDialog;

export const showConfigFlowDialog = (
element: HTMLElement,
dialogParams: Omit<DataEntryFlowDialogParams, "flowConfig">
dialogParams: Omit<DataEntryFlowDialogParams, "flowConfig"> & {
entryId?: string;
}
): void =>
showFlowDialog(element, dialogParams, {
flowType: "config_flow",
Expand Down
1 change: 0 additions & 1 deletion src/dialogs/config-flow/show-dialog-data-entry-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export interface DataEntryFlowDialogParams {
}) => void;
flowConfig: FlowConfig;
showAdvanced?: boolean;
entryId?: string;
dialogParentElement?: HTMLElement;
navigateToResult?: boolean;
}
Expand Down
Loading

0 comments on commit 0d97afb

Please sign in to comment.