Change add application credential flow (#13951)

* Change add application credential flow

* Update step-flow-abort.ts

* import

* Add missing credential docs link

* Load description, show only that if available

* Update dialog-add-application-credential.ts

* pass along manifest

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Bram Kragten 2022-10-02 20:19:32 +02:00 committed by GitHub
parent c14d9ab957
commit cb0310593c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 63 deletions

View File

@ -14,8 +14,6 @@ import { showAddApplicationCredentialDialog } from "../../panels/config/applicat
import { configFlowContentStyles } from "./styles"; import { configFlowContentStyles } from "./styles";
import { DataEntryFlowDialogParams } from "./show-dialog-data-entry-flow"; import { DataEntryFlowDialogParams } from "./show-dialog-data-entry-flow";
import { showConfigFlowDialog } from "./show-dialog-config-flow"; import { showConfigFlowDialog } from "./show-dialog-config-flow";
import { domainToName } from "../../data/integration";
import { showConfirmationDialog } from "../generic/show-dialog-box";
@customElement("step-flow-abort") @customElement("step-flow-abort")
class StepFlowAbort extends LitElement { class StepFlowAbort extends LitElement {
@ -54,26 +52,11 @@ class StepFlowAbort extends LitElement {
} }
private async _handleMissingCreds() { private async _handleMissingCreds() {
const confirm = await showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.integrations.config_flow.missing_credentials_title"
),
text: this.hass.localize(
"ui.panel.config.integrations.config_flow.missing_credentials",
{
integration: domainToName(this.hass.localize, this.domain),
}
),
confirmText: this.hass.localize("ui.common.yes"),
dismissText: this.hass.localize("ui.common.no"),
});
this._flowDone(); this._flowDone();
if (!confirm) {
return;
}
// Prompt to enter credentials and restart integration setup // Prompt to enter credentials and restart integration setup
showAddApplicationCredentialDialog(this.params.dialogParentElement!, { showAddApplicationCredentialDialog(this.params.dialogParentElement!, {
selectedDomain: this.domain, selectedDomain: this.domain,
manifest: this.params.manifest,
applicationCredentialAddedCallback: () => { applicationCredentialAddedCallback: () => {
showConfigFlowDialog(this.params.dialogParentElement!, { showConfigFlowDialog(this.params.dialogParentElement!, {
dialogClosedCallback: this.params.dialogClosedCallback, dialogClosedCallback: this.params.dialogClosedCallback,

View File

@ -5,6 +5,7 @@ import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-alert";
import "../../../components/ha-circular-progress"; import "../../../components/ha-circular-progress";
import "../../../components/ha-combo-box"; import "../../../components/ha-combo-box";
import { createCloseHeading } from "../../../components/ha-dialog"; import { createCloseHeading } from "../../../components/ha-dialog";
@ -16,7 +17,7 @@ import {
createApplicationCredential, createApplicationCredential,
fetchApplicationCredentialsConfig, fetchApplicationCredentialsConfig,
} from "../../../data/application_credential"; } from "../../../data/application_credential";
import { domainToName } from "../../../data/integration"; import { domainToName, IntegrationManifest } from "../../../data/integration";
import { haStyleDialog } from "../../../resources/styles"; import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { documentationUrl } from "../../../util/documentation-url"; import { documentationUrl } from "../../../util/documentation-url";
@ -44,6 +45,8 @@ export class DialogAddApplicationCredential extends LitElement {
@state() private _domain?: string; @state() private _domain?: string;
@state() private _manifest?: IntegrationManifest | null;
@state() private _name?: string; @state() private _name?: string;
@state() private _description?: string; @state() private _description?: string;
@ -58,8 +61,8 @@ export class DialogAddApplicationCredential extends LitElement {
public showDialog(params: AddApplicationCredentialDialogParams) { public showDialog(params: AddApplicationCredentialDialogParams) {
this._params = params; this._params = params;
this._domain = this._domain = params.selectedDomain;
params.selectedDomain !== undefined ? params.selectedDomain : ""; this._manifest = params.manifest;
this._name = ""; this._name = "";
this._description = ""; this._description = "";
this._clientId = ""; this._clientId = "";
@ -76,7 +79,7 @@ export class DialogAddApplicationCredential extends LitElement {
name: domainToName(this.hass.localize, domain), name: domainToName(this.hass.localize, domain),
})); }));
await this.hass.loadBackendTranslation("application_credentials"); await this.hass.loadBackendTranslation("application_credentials");
if (this._domain !== "") { if (this._domain) {
this._updateDescription(); this._updateDescription();
} }
} }
@ -85,6 +88,9 @@ export class DialogAddApplicationCredential extends LitElement {
if (!this._params || !this._domains) { if (!this._params || !this._domains) {
return html``; return html``;
} }
const selectedDomainName = this._params.selectedDomain
? domainToName(this.hass.localize, this._domain!)
: "";
return html` return html`
<ha-dialog <ha-dialog
open open
@ -99,42 +105,76 @@ export class DialogAddApplicationCredential extends LitElement {
)} )}
> >
<div> <div>
${this._error ? html` <div class="error">${this._error}</div> ` : ""} ${this._error
<p> ? html`<ha-alert alert-type="error">${this._error}</ha-alert> `
${this.hass.localize( : ""}
"ui.panel.config.application_credentials.editor.description" ${this._params.selectedDomain && !this._description
)} ? html`<p>
<br /> ${this.hass.localize(
<a "ui.panel.config.application_credentials.editor.missing_credentials",
href=${documentationUrl( {
this.hass!, integration: selectedDomainName,
"/integrations/application_credentials" }
)} )}
target="_blank" ${this._manifest?.is_built_in || this._manifest?.documentation
rel="noreferrer" ? html`<a
> href=${this._manifest.is_built_in
${this.hass!.localize( ? documentationUrl(
"ui.panel.config.application_credentials.editor.view_documentation" this.hass,
)} `/integrations/${this._domain}`
<ha-svg-icon .path=${mdiOpenInNew}></ha-svg-icon> )
</a> : this._manifest.documentation}
</p> target="_blank"
<ha-combo-box rel="noreferrer"
name="domain" >
.hass=${this.hass} ${this.hass.localize(
.disabled=${!!this._params.selectedDomain} "ui.panel.config.application_credentials.editor.missing_credentials_domain_link",
.label=${this.hass.localize( {
"ui.panel.config.application_credentials.editor.domain" integration: selectedDomainName,
)} }
.value=${this._domain} )}
.renderer=${rowRenderer} <ha-svg-icon .path=${mdiOpenInNew}></ha-svg-icon>
.items=${this._domains} </a>`
item-id-path="id" : ""}
item-value-path="id" </p>`
item-label-path="name" : ""}
required ${!this._params.selectedDomain || !this._description
@value-changed=${this._handleDomainPicked} ? html`<p>
></ha-combo-box> ${this.hass.localize(
"ui.panel.config.application_credentials.editor.description"
)}
<a
href=${documentationUrl(
this.hass!,
"/integrations/application_credentials"
)}
target="_blank"
rel="noreferrer"
>
${this.hass!.localize(
"ui.panel.config.application_credentials.editor.view_documentation"
)}
<ha-svg-icon .path=${mdiOpenInNew}></ha-svg-icon>
</a>
</p>`
: ""}
${this._params.selectedDomain
? ""
: html`<ha-combo-box
name="domain"
.hass=${this.hass}
.label=${this.hass.localize(
"ui.panel.config.application_credentials.editor.domain"
)}
.value=${this._domain}
.renderer=${rowRenderer}
.items=${this._domains}
item-id-path="id"
item-value-path="id"
item-label-path="name"
required
@value-changed=${this._handleDomainPicked}
></ha-combo-box>`}
${this._description ${this._description
? html`<ha-markdown ? html`<ha-markdown
breaks breaks
@ -223,7 +263,11 @@ export class DialogAddApplicationCredential extends LitElement {
this._updateDescription(); this._updateDescription();
} }
private _updateDescription() { private async _updateDescription() {
await this.hass.loadBackendTranslation(
"application_credentials",
this._domain
);
const info = this._config!.integrations[this._domain!]; const info = this._config!.integrations[this._domain!];
this._description = this.hass.localize( this._description = this.hass.localize(
`component.${this._domain}.application_credentials.description`, `component.${this._domain}.application_credentials.description`,
@ -298,6 +342,9 @@ export class DialogAddApplicationCredential extends LitElement {
a ha-svg-icon { a ha-svg-icon {
--mdc-icon-size: 16px; --mdc-icon-size: 16px;
} }
ha-markdown {
margin-bottom: 16px;
}
`, `,
]; ];
} }

View File

@ -1,5 +1,6 @@
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { ApplicationCredential } from "../../../data/application_credential"; import { ApplicationCredential } from "../../../data/application_credential";
import { IntegrationManifest } from "../../../data/integration";
export interface AddApplicationCredentialDialogParams { export interface AddApplicationCredentialDialogParams {
applicationCredentialAddedCallback: ( applicationCredentialAddedCallback: (
@ -7,6 +8,7 @@ export interface AddApplicationCredentialDialogParams {
) => void; ) => void;
dialogAbortedCallback?: () => void; dialogAbortedCallback?: () => void;
selectedDomain?: string; selectedDomain?: string;
manifest?: IntegrationManifest | null;
} }
export const loadAddApplicationCredentialDialog = () => export const loadAddApplicationCredentialDialog = () =>

View File

@ -192,7 +192,10 @@ class HaDomainIntegrations extends LitElement {
} }
if ( if (
(domain === this.domain && !this.integration!.config_flow) || (domain === this.domain &&
!this.integration!.config_flow &&
(!this.integration!.integrations?.[domain] ||
!this.integration!.integrations[domain].config_flow)) ||
!this.integration!.integrations?.[domain]?.config_flow !this.integration!.integrations?.[domain]?.config_flow
) { ) {
const manifest = await fetchIntegrationManifest(this.hass, domain); const manifest = await fetchIntegrationManifest(this.hass, domain);

View File

@ -2985,8 +2985,6 @@
"error": "Error", "error": "Error",
"could_not_load": "Config flow could not be loaded", "could_not_load": "Config flow could not be loaded",
"not_loaded": "The integration could not be loaded, try to restart Home Assistant.", "not_loaded": "The integration could not be loaded, try to restart Home Assistant.",
"missing_credentials_title": "Add application credentials?",
"missing_credentials": "Setting up {integration} requires configuring application credentials. Do you want to do that now?",
"supported_brand_flow": "Support for {supported_brand} devices is provided by {flow_domain_name}. Do you want to continue?", "supported_brand_flow": "Support for {supported_brand} devices is provided by {flow_domain_name}. Do you want to continue?",
"missing_zwave_zigbee": "To add a {integration} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.", "missing_zwave_zigbee": "To add a {integration} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.",
"supported_hardware": "supported hardware", "supported_hardware": "supported hardware",
@ -3059,7 +3057,9 @@
"editor": { "editor": {
"caption": "Add Credential", "caption": "Add Credential",
"description": "OAuth is used to grant Home Assistant access to information on other websites without giving a passwords. This mechanism is used by companies such as Spotify, Google, Withings, Microsoft, and Twitter.", "description": "OAuth is used to grant Home Assistant access to information on other websites without giving a passwords. This mechanism is used by companies such as Spotify, Google, Withings, Microsoft, and Twitter.",
"view_documentation": "View documentation", "missing_credentials": "Setting up {integration} requires configuring application credentials.",
"missing_credentials_domain_link": "View {integration} documentation",
"view_documentation": "View application credentials documentation",
"add": "Add", "add": "Add",
"domain": "Integration", "domain": "Integration",
"name": "Name", "name": "Name",