Split store and installed calls (#12921)

* Split store and installed calls

* Fix issue when installing

* Remove supervisor.addons usage

* one more

* Update core

* Comments
This commit is contained in:
Joakim Sørensen 2022-06-11 11:04:54 +02:00 committed by GitHub
parent 0926202eca
commit e7848262ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 107 additions and 60 deletions

View File

@ -12,15 +12,17 @@ import { navigate } from "../../../src/common/navigate";
import { extractSearchParam } from "../../../src/common/url/search-params"; import { extractSearchParam } from "../../../src/common/url/search-params";
import "../../../src/components/ha-circular-progress"; import "../../../src/components/ha-circular-progress";
import { import {
fetchAddonInfo,
fetchHassioAddonInfo, fetchHassioAddonInfo,
fetchHassioAddonsInfo, fetchHassioAddonsInfo,
HassioAddonDetails, HassioAddonDetails,
} from "../../../src/data/hassio/addon"; } from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common"; import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { import {
fetchHassioSupervisorInfo, addStoreRepository,
setSupervisorOption, fetchSupervisorStore,
} from "../../../src/data/hassio/supervisor"; StoreAddonDetails,
} from "../../../src/data/supervisor/store";
import { Supervisor } from "../../../src/data/supervisor/supervisor"; import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { showConfirmationDialog } from "../../../src/dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../src/dialogs/generic/show-dialog-box";
import "../../../src/layouts/hass-error-screen"; import "../../../src/layouts/hass-error-screen";
@ -45,7 +47,9 @@ class HassioAddonDashboard extends LitElement {
@property({ attribute: false }) public route!: Route; @property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public addon?: HassioAddonDetails; @property({ attribute: false }) public addon?:
| HassioAddonDetails
| StoreAddonDetails;
@property({ type: Boolean }) public narrow!: boolean; @property({ type: Boolean }) public narrow!: boolean;
@ -173,10 +177,10 @@ class HassioAddonDashboard extends LitElement {
const requestedAddon = extractSearchParam("addon"); const requestedAddon = extractSearchParam("addon");
const requestedAddonRepository = extractSearchParam("repository_url"); const requestedAddonRepository = extractSearchParam("repository_url");
if (requestedAddonRepository) { if (requestedAddonRepository) {
const supervisorInfo = await fetchHassioSupervisorInfo(this.hass); const storeInfo = await fetchSupervisorStore(this.hass);
if ( if (
!supervisorInfo.addons_repositories.find( !storeInfo.repositories.find(
(repo) => repo === requestedAddonRepository (repo) => repo.source === requestedAddonRepository
) )
) { ) {
if ( if (
@ -197,12 +201,7 @@ class HassioAddonDashboard extends LitElement {
} }
try { try {
await setSupervisorOption(this.hass, { await addStoreRepository(this.hass, requestedAddonRepository);
addons_repositories: [
...supervisorInfo.addons_repositories,
requestedAddonRepository,
],
});
} catch (err: any) { } catch (err: any) {
this._error = extractApiErrorMessage(err); this._error = extractApiErrorMessage(err);
} }
@ -245,6 +244,8 @@ class HassioAddonDashboard extends LitElement {
if (path === "uninstall") { if (path === "uninstall") {
window.history.back(); window.history.back();
} else if (path === "install") {
this.addon = await fetchHassioAddonInfo(this.hass, this.addon!.slug);
} else { } else {
await this._routeDataChanged(); await this._routeDataChanged();
} }
@ -262,8 +263,7 @@ class HassioAddonDashboard extends LitElement {
return; return;
} }
try { try {
const addoninfo = await fetchHassioAddonInfo(this.hass, addon); this.addon = await fetchAddonInfo(this.hass, this.supervisor, addon);
this.addon = addoninfo;
} catch (err: any) { } catch (err: any) {
this._error = `Error fetching addon info: ${extractApiErrorMessage(err)}`; this._error = `Error fetching addon info: ${extractApiErrorMessage(err)}`;
this.addon = undefined; this.addon = undefined;

View File

@ -1,5 +1,6 @@
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { HassioAddonDetails } from "../../../src/data/hassio/addon"; import { HassioAddonDetails } from "../../../src/data/hassio/addon";
import { StoreAddonDetails } from "../../../src/data/supervisor/store";
import { Supervisor } from "../../../src/data/supervisor/supervisor"; import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { import {
HassRouterPage, HassRouterPage,
@ -20,7 +21,9 @@ class HassioAddonRouter extends HassRouterPage {
@property({ attribute: false }) public supervisor!: Supervisor; @property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public addon!: HassioAddonDetails; @property({ attribute: false }) public addon!:
| HassioAddonDetails
| StoreAddonDetails;
protected routerOptions: RouterOptions = { protected routerOptions: RouterOptions = {
defaultPage: "info", defaultPage: "info",

View File

@ -59,7 +59,10 @@ import {
fetchHassioStats, fetchHassioStats,
HassioStats, HassioStats,
} from "../../../../src/data/hassio/common"; } from "../../../../src/data/hassio/common";
import { StoreAddon } from "../../../../src/data/supervisor/store"; import {
StoreAddon,
StoreAddonDetails,
} from "../../../../src/data/supervisor/store";
import { Supervisor } from "../../../../src/data/supervisor/supervisor"; import { Supervisor } from "../../../../src/data/supervisor/supervisor";
import { import {
showAlertDialog, showAlertDialog,
@ -100,7 +103,9 @@ class HassioAddonInfo extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon!: HassioAddonDetails; @property({ attribute: false }) public addon!:
| HassioAddonDetails
| StoreAddonDetails;
@property({ attribute: false }) public supervisor!: Supervisor; @property({ attribute: false }) public supervisor!: Supervisor;
@ -143,7 +148,7 @@ class HassioAddonInfo extends LitElement {
></update-available-card> ></update-available-card>
` `
: ""} : ""}
${!this.addon.protected ${"protected" in this.addon && !this.addon.protected
? html` ? html`
<ha-alert <ha-alert
alert-type="error" alert-type="error"
@ -518,7 +523,7 @@ class HassioAddonInfo extends LitElement {
: ""} : ""}
</div> </div>
<div> <div>
${this.addon.state === "started" ${this.addon.version && this.addon.state === "started"
? html`<ha-settings-row ?three-line=${this.narrow}> ? html`<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading"> <span slot="heading">
${this.supervisor.localize("addon.dashboard.hostname")} ${this.supervisor.localize("addon.dashboard.hostname")}
@ -669,7 +674,7 @@ class HassioAddonInfo extends LitElement {
} }
private async _loadData(): Promise<void> { private async _loadData(): Promise<void> {
if (this.addon.state === "started") { if ("state" in this.addon && this.addon.state === "started") {
this._metrics = await fetchHassioStats( this._metrics = await fetchHassioStats(
this.hass, this.hass,
`addons/${this.addon.slug}` `addons/${this.addon.slug}`
@ -717,18 +722,22 @@ class HassioAddonInfo extends LitElement {
} }
private get _computeIsRunning(): boolean { private get _computeIsRunning(): boolean {
return this.addon?.state === "started"; return (this.addon as HassioAddonDetails)?.state === "started";
} }
private get _pathWebui(): string | null { private get _pathWebui(): string | null {
return ( return (this.addon as HassioAddonDetails).webui!.replace(
this.addon.webui && "[HOST]",
this.addon.webui.replace("[HOST]", document.location.hostname) document.location.hostname
); );
} }
private get _computeShowWebUI(): boolean | "" | null { private get _computeShowWebUI(): boolean | "" | null {
return !this.addon.ingress && this.addon.webui && this._computeIsRunning; return (
!this.addon.ingress &&
(this.addon as HassioAddonDetails).webui &&
this._computeIsRunning
);
} }
private _openIngress(): void { private _openIngress(): void {
@ -754,7 +763,8 @@ class HassioAddonInfo extends LitElement {
private async _startOnBootToggled(): Promise<void> { private async _startOnBootToggled(): Promise<void> {
this._error = undefined; this._error = undefined;
const data: HassioAddonSetOptionParams = { const data: HassioAddonSetOptionParams = {
boot: this.addon.boot === "auto" ? "manual" : "auto", boot:
(this.addon as HassioAddonDetails).boot === "auto" ? "manual" : "auto",
}; };
try { try {
await setHassioAddonOption(this.hass, this.addon.slug, data); await setHassioAddonOption(this.hass, this.addon.slug, data);
@ -776,7 +786,7 @@ class HassioAddonInfo extends LitElement {
private async _watchdogToggled(): Promise<void> { private async _watchdogToggled(): Promise<void> {
this._error = undefined; this._error = undefined;
const data: HassioAddonSetOptionParams = { const data: HassioAddonSetOptionParams = {
watchdog: !this.addon.watchdog, watchdog: !(this.addon as HassioAddonDetails).watchdog,
}; };
try { try {
await setHassioAddonOption(this.hass, this.addon.slug, data); await setHassioAddonOption(this.hass, this.addon.slug, data);
@ -798,7 +808,7 @@ class HassioAddonInfo extends LitElement {
private async _autoUpdateToggled(): Promise<void> { private async _autoUpdateToggled(): Promise<void> {
this._error = undefined; this._error = undefined;
const data: HassioAddonSetOptionParams = { const data: HassioAddonSetOptionParams = {
auto_update: !this.addon.auto_update, auto_update: !(this.addon as HassioAddonDetails).auto_update,
}; };
try { try {
await setHassioAddonOption(this.hass, this.addon.slug, data); await setHassioAddonOption(this.hass, this.addon.slug, data);
@ -820,7 +830,7 @@ class HassioAddonInfo extends LitElement {
private async _protectionToggled(): Promise<void> { private async _protectionToggled(): Promise<void> {
this._error = undefined; this._error = undefined;
const data: HassioAddonSetSecurityParams = { const data: HassioAddonSetSecurityParams = {
protected: !this.addon.protected, protected: !(this.addon as HassioAddonDetails).protected,
}; };
try { try {
await setHassioAddonSecurity(this.hass, this.addon.slug, data); await setHassioAddonSecurity(this.hass, this.addon.slug, data);
@ -842,7 +852,7 @@ class HassioAddonInfo extends LitElement {
private async _panelToggled(): Promise<void> { private async _panelToggled(): Promise<void> {
this._error = undefined; this._error = undefined;
const data: HassioAddonSetOptionParams = { const data: HassioAddonSetOptionParams = {
ingress_panel: !this.addon.ingress_panel, ingress_panel: !(this.addon as HassioAddonDetails).ingress_panel,
}; };
try { try {
await setHassioAddonOption(this.hass, this.addon.slug, data); await setHassioAddonOption(this.hass, this.addon.slug, data);
@ -870,7 +880,7 @@ class HassioAddonInfo extends LitElement {
showHassioMarkdownDialog(this, { showHassioMarkdownDialog(this, {
title: this.supervisor.localize("addon.dashboard.changelog"), title: this.supervisor.localize("addon.dashboard.changelog"),
content: extractChangelog(this.addon, content), content: extractChangelog(this.addon as HassioAddonDetails, content),
}); });
} catch (err: any) { } catch (err: any) {
showAlertDialog(this, { showAlertDialog(this, {

View File

@ -98,9 +98,8 @@ export class HassioBackups extends LitElement {
if (backup.content.addons.length !== 0) { if (backup.content.addons.length !== 0) {
for (const addon of backup.content.addons) { for (const addon of backup.content.addons) {
content.push( content.push(
this.supervisor.supervisor.addons.find( this.supervisor.addon.addons.find((entry) => entry.slug === addon)
(entry) => entry.slug === addon ?.name || addon
)?.name || addon
); );
} }
} }

View File

@ -96,7 +96,7 @@ export class SupervisorBackupContent extends LitElement {
: ["ssl", "share", "media", "addons/local"] : ["ssl", "share", "media", "addons/local"]
); );
this.addons = _computeAddons( this.addons = _computeAddons(
this.backup ? this.backup.addons : this.supervisor?.supervisor.addons this.backup ? this.backup.addons : this.supervisor?.addon.addons
); );
this.backupType = this.backup?.type || "full"; this.backupType = this.backup?.type || "full";
this.backupName = this.backup?.name || ""; this.backupName = this.backup?.name || "";

View File

@ -24,7 +24,7 @@ class HassioAddons extends LitElement {
? html` <h1>${this.supervisor.localize("dashboard.addons")}</h1> ` ? html` <h1>${this.supervisor.localize("dashboard.addons")}</h1> `
: ""} : ""}
<div class="card-group"> <div class="card-group">
${!this.supervisor.supervisor.addons?.length ${!this.supervisor.addon.addons.length
? html` ? html`
<ha-card outlined> <ha-card outlined>
<div class="card-content"> <div class="card-content">
@ -34,7 +34,7 @@ class HassioAddons extends LitElement {
</div> </div>
</ha-card> </ha-card>
` `
: this.supervisor.supervisor.addons : this.supervisor.addon.addons
.sort((a, b) => caseInsensitiveStringCompare(a.name, b.name)) .sort((a, b) => caseInsensitiveStringCompare(a.name, b.name))
.map( .map(
(addon) => html` (addon) => html`

View File

@ -87,7 +87,7 @@ class HassioRepositoriesDialog extends LitElement {
const repositories = this._filteredRepositories(this._repositories); const repositories = this._filteredRepositories(this._repositories);
const usedRepositories = this._filteredUsedRepositories( const usedRepositories = this._filteredUsedRepositories(
repositories, repositories,
this._dialogParams.supervisor.supervisor.addons this._dialogParams.supervisor.addon.addons
); );
return html` return html`
<ha-dialog <ha-dialog

View File

@ -4,8 +4,7 @@ import { customElement, property, query, state } from "lit/decorators";
import { isComponentLoaded } from "../common/config/is_component_loaded"; import { isComponentLoaded } from "../common/config/is_component_loaded";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { stringCompare } from "../common/string/compare"; import { stringCompare } from "../common/string/compare";
import { HassioAddonInfo } from "../data/hassio/addon"; import { fetchHassioAddonsInfo, HassioAddonInfo } from "../data/hassio/addon";
import { fetchHassioSupervisorInfo } from "../data/hassio/supervisor";
import { showAlertDialog } from "../dialogs/generic/show-dialog-box"; import { showAlertDialog } from "../dialogs/generic/show-dialog-box";
import { PolymerChangedEvent } from "../polymer-types"; import { PolymerChangedEvent } from "../polymer-types";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
@ -78,10 +77,10 @@ class HaAddonPicker extends LitElement {
private async _getAddons() { private async _getAddons() {
try { try {
if (isComponentLoaded(this.hass, "hassio")) { if (isComponentLoaded(this.hass, "hassio")) {
const supervisorInfo = await fetchHassioSupervisorInfo(this.hass); const addonsInfo = await fetchHassioAddonsInfo(this.hass);
this._addons = supervisorInfo.addons.sort((a, b) => this._addons = addonsInfo.addons
stringCompare(a.name, b.name) .filter((addon) => addon.version)
); .sort((a, b) => stringCompare(a.name, b.name));
} else { } else {
showAlertDialog(this, { showAlertDialog(this, {
title: this.hass.localize( title: this.hass.localize(

View File

@ -1,7 +1,9 @@
import { atLeastVersion } from "../../common/config/version"; import { atLeastVersion } from "../../common/config/version";
import type { HaFormSchema } from "../../components/ha-form/types"; import type { HaFormSchema } from "../../components/ha-form/types";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import { SupervisorArch } from "../supervisor/supervisor"; import { supervisorApiCall } from "../supervisor/common";
import { StoreAddonDetails } from "../supervisor/store";
import { Supervisor, SupervisorArch } from "../supervisor/supervisor";
import { import {
extractApiErrorMessage, extractApiErrorMessage,
hassioApiResultExtractor, hassioApiResultExtractor,
@ -363,3 +365,15 @@ export const uninstallHassioAddon = async (
`hassio/addons/${slug}/uninstall` `hassio/addons/${slug}/uninstall`
); );
}; };
export const fetchAddonInfo = (
hass: HomeAssistant,
supervisor: Supervisor,
addonSlug: string
): Promise<HassioAddonDetails | StoreAddonDetails> =>
supervisorApiCall(
hass,
!supervisor.addon?.addons.find((addon) => addon.slug === addonSlug)
? `/store/addons/${addonSlug}` // Use /store/addons when add-on is not installed
: `/addons/${addonSlug}/info` // Use /addons when add-on is installed
);

View File

@ -1,7 +1,6 @@
import { atLeastVersion } from "../../common/config/version"; import { atLeastVersion } from "../../common/config/version";
import { HomeAssistant, PanelInfo } from "../../types"; import { HomeAssistant, PanelInfo } from "../../types";
import { SupervisorArch } from "../supervisor/supervisor"; import { SupervisorArch } from "../supervisor/supervisor";
import { HassioAddonInfo } from "./addon";
import { hassioApiResultExtractor, HassioResponse } from "./common"; import { hassioApiResultExtractor, HassioResponse } from "./common";
export type HassioHomeAssistantInfo = { export type HassioHomeAssistantInfo = {
@ -22,7 +21,7 @@ export type HassioHomeAssistantInfo = {
}; };
export type HassioSupervisorInfo = { export type HassioSupervisorInfo = {
addons: HassioAddonInfo[]; addons: string[];
addons_repositories: string[]; addons_repositories: string[];
arch: SupervisorArch; arch: SupervisorArch;
channel: string; channel: string;

View File

@ -1,6 +1,7 @@
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import { AddonRepository, AddonStage } from "../hassio/addon"; import { AddonStage } from "../hassio/addon";
import { supervisorApiCall } from "./common"; import { supervisorApiCall } from "./common";
import { SupervisorArch } from "./supervisor";
export interface StoreAddon { export interface StoreAddon {
advanced: boolean; advanced: boolean;
@ -12,14 +13,34 @@ export interface StoreAddon {
installed: boolean; installed: boolean;
logo: boolean; logo: boolean;
name: string; name: string;
repository: AddonRepository; repository: string;
slug: string; slug: string;
stage: AddonStage; stage: AddonStage;
update_available: boolean; update_available: boolean;
url: string; url: string;
version: string | null;
version_latest: string; version_latest: string;
version: null;
} }
export interface StoreAddonDetails extends StoreAddon {
apparmor: boolean;
arch: SupervisorArch[];
auth_api: boolean;
detached: boolean;
docker_api: boolean;
documentation: boolean;
full_access: boolean;
hassio_api: boolean;
hassio_role: string;
homeassistant_api: boolean;
host_network: boolean;
host_pid: boolean;
ingress: boolean;
long_description: string;
rating: number;
signed: boolean;
}
interface StoreRepository { interface StoreRepository {
maintainer: string; maintainer: string;
name: string; name: string;

View File

@ -34,7 +34,7 @@ import "../../components/ha-circular-progress";
import "../../components/ha-header-bar"; import "../../components/ha-header-bar";
import "../../components/ha-icon-button"; import "../../components/ha-icon-button";
import "../../components/ha-textfield"; import "../../components/ha-textfield";
import { fetchHassioSupervisorInfo } from "../../data/hassio/supervisor"; import { fetchHassioAddonsInfo } from "../../data/hassio/addon";
import { domainToName } from "../../data/integration"; import { domainToName } from "../../data/integration";
import { getPanelNameTranslationKey } from "../../data/panel"; import { getPanelNameTranslationKey } from "../../data/panel";
import { PageNavigation } from "../../layouts/hass-tabs-subpage"; import { PageNavigation } from "../../layouts/hass-tabs-subpage";
@ -586,7 +586,7 @@ export class QuickBar extends LitElement {
const sectionItems = this._generateNavigationConfigSectionCommands(); const sectionItems = this._generateNavigationConfigSectionCommands();
const supervisorItems: BaseNavigationCommand[] = []; const supervisorItems: BaseNavigationCommand[] = [];
if (isComponentLoaded(this.hass, "hassio")) { if (isComponentLoaded(this.hass, "hassio")) {
const supervisorInfo = await fetchHassioSupervisorInfo(this.hass); const addonsInfo = await fetchHassioAddonsInfo(this.hass);
supervisorItems.push({ supervisorItems.push({
path: "/hassio/store", path: "/hassio/store",
primaryText: this.hass.localize( primaryText: this.hass.localize(
@ -599,7 +599,7 @@ export class QuickBar extends LitElement {
"ui.dialogs.quick-bar.commands.navigation.addon_dashboard" "ui.dialogs.quick-bar.commands.navigation.addon_dashboard"
), ),
}); });
for (const addon of supervisorInfo.addons) { for (const addon of addonsInfo.addons.filter((a) => a.version)) {
supervisorItems.push({ supervisorItems.push({
path: `/hassio/addon/${addon.slug}`, path: `/hassio/addon/${addon.slug}`,
primaryText: this.hass.localize( primaryText: this.hass.localize(

View File

@ -6,7 +6,7 @@ import { extractSearchParam } from "../../../common/url/search-params";
import "../../../components/ha-button-menu"; import "../../../components/ha-button-menu";
import "../../../components/search-input"; import "../../../components/search-input";
import { LogProvider } from "../../../data/error_log"; import { LogProvider } from "../../../data/error_log";
import { fetchHassioSupervisorInfo } from "../../../data/hassio/supervisor"; import { fetchHassioAddonsInfo } from "../../../data/hassio/addon";
import "../../../layouts/hass-subpage"; import "../../../layouts/hass-subpage";
import "../../../layouts/hass-tabs-subpage"; import "../../../layouts/hass-tabs-subpage";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
@ -167,13 +167,15 @@ export class HaConfigLogs extends LitElement {
private async _getInstalledAddons() { private async _getInstalledAddons() {
try { try {
const supervisorInfo = await fetchHassioSupervisorInfo(this.hass); const addonsInfo = await fetchHassioAddonsInfo(this.hass);
this._logProviders = [ this._logProviders = [
...this._logProviders, ...this._logProviders,
...supervisorInfo.addons.map((addon) => ({ ...addonsInfo.addons
key: addon.slug, .filter((addon) => addon.version)
name: addon.name, .map((addon) => ({
})), key: addon.slug,
name: addon.name,
})),
]; ];
} catch (err) { } catch (err) {
// Ignore, nothing the user can do anyway // Ignore, nothing the user can do anyway