Integration Quality Scale indicator (#23015)

This commit is contained in:
Wendelin 2024-11-27 14:45:44 +01:00 committed by GitHub
parent f54bb20fef
commit bc195c61cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 118 additions and 44 deletions

View File

@ -38,7 +38,7 @@ export interface IntegrationManifest {
homekit?: { models: string[] };
integration_type?: IntegrationType;
loggers?: string[];
quality_scale?: "gold" | "internal" | "platinum" | "silver";
quality_scale?: "bronze" | "gold" | "internal" | "platinum" | "silver";
iot_class:
| "assumed_state"
| "cloud_polling"

View File

@ -6,7 +6,6 @@ import {
mdiBug,
mdiBugPlay,
mdiBugStop,
mdiCloud,
mdiCog,
mdiDelete,
mdiDevices,
@ -14,6 +13,7 @@ import {
mdiDownload,
mdiFileCodeOutline,
mdiHandExtendedOutline,
mdiMedal,
mdiOpenInNew,
mdiPackageVariant,
mdiPlayCircleOutline,
@ -23,6 +23,8 @@ import {
mdiRenameBox,
mdiShapeOutline,
mdiStopCircleOutline,
mdiTrophy,
mdiWeb,
mdiWrench,
} from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
@ -338,41 +340,72 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
${this._manifest?.version != null
? html`<div class="version">${this._manifest.version}</div>`
: nothing}
${this._manifest?.quality_scale &&
this._manifest?.quality_scale !== "internal"
? html`
<div class="quality-scale integration-info">
<ha-svg-icon
class=${`${this._manifest.quality_scale}-medal`}
.path=${this._manifest.quality_scale === "platinum"
? mdiTrophy
: mdiMedal}
></ha-svg-icon>
<span>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.${this._manifest.quality_scale}_quality`,
{
quality_scale: html`
<a
href=${documentationUrl(
this.hass,
`/docs/quality_scale/#${this._manifest.quality_scale}-`
)}
rel="noopener noreferrer"
target="_blank"
>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.quality_scale"
)}
</a>
`,
}
)}
</span>
</div>
`
: nothing}
${this._manifest?.is_built_in === false
? html`<ha-alert alert-type="warning"
><ha-svg-icon
slot="icon"
? html`<div class="integration-info warn">
<ha-svg-icon
class="warning"
path=${mdiPackageVariant}
></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.custom_integration"
)}</ha-alert
>`
: ""}
)}
</div>`
: nothing}
${this._manifest?.iot_class?.startsWith("cloud_")
? html`<ha-alert
><ha-svg-icon slot="icon" path=${mdiCloud}></ha-svg-icon
>${this.hass.localize(
? html`<div class="integration-info">
<ha-svg-icon .path=${mdiWeb}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.depends_on_cloud"
)}</ha-alert
>`
: ""}
)}
</div>`
: nothing}
${normalEntries.length === 0 &&
this._manifest &&
!this._manifest.config_flow &&
this.hass.config.components.find(
(comp) => comp.split(".")[0] === this.domain
)
? html`<ha-alert alert-type="info"
><ha-svg-icon
slot="icon"
path=${mdiFileCodeOutline}
></ha-svg-icon
? html`<div class="integration-info info">
<ha-svg-icon path=${mdiFileCodeOutline}></ha-svg-icon
>${this.hass.localize(
"ui.panel.config.integrations.config_entry.no_config_flow"
)}</ha-alert
>`
: ""}
)}
</div>`
: nothing}
</div>
<div class="card-actions">
@ -398,7 +431,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
: nothing}
${numberOfEntities > 0
? html`<a
href=${`/config/entities?historyBack=1&domain=${this.domain}`}
@ -415,7 +448,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
: nothing}
${this._manifest
? html`<a
href=${this._manifest.is_built_in
@ -441,7 +474,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
></ha-svg-icon>
</ha-list-item>
</a>`
: ""}
: nothing}
${this._manifest &&
(this._manifest.is_built_in || this._manifest.issue_tracker)
? html`<a
@ -463,7 +496,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
></ha-svg-icon>
</ha-list-item>
</a>`
: ""}
: nothing}
${this._logInfo
? html`<ha-list-item
@request-selected=${this._logInfo.level ===
@ -489,7 +522,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
: mdiBugPlay}
></ha-svg-icon>
</ha-list-item>`
: ""}
: nothing}
</div>
</ha-card>
</div>
@ -517,7 +550,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
)}
</ha-md-list>
</ha-card>`
: ""}
: nothing}
${attentionFlows.length || attentionEntries.length
? html`<ha-card>
<h1 class="card-header">
@ -562,11 +595,11 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
role="separator"
tabindex="-1"
></ha-md-divider>`
: ""} `
: nothing} `
)}
</ha-md-list>
</ha-card>`
: ""}
: nothing}
<ha-card>
<h1 class="card-header">
@ -602,7 +635,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
role="separator"
tabindex="-1"
></ha-md-divider>`
: ""} `
: nothing}`
)}
</ha-md-list>
<div class="card-actions">
@ -762,11 +795,11 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<div>
${this.hass.localize(...stateText)}${stateTextExtra
? html`: ${stateTextExtra}`
: ""}
: nothing}
</div>
</div>
`
: ""}
: nothing}
</div>
${item.disabled_by === "user"
? html`<ha-button unelevated slot="end" @click=${this._handleEnable}>
@ -793,7 +826,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
)}
</ha-button>
`
: ""}
: nothing}
<ha-md-button-menu positioning="popover" slot="end">
<ha-icon-button
slot="trigger"
@ -815,7 +848,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<ha-icon-next slot="end"></ha-icon-next>
</ha-md-menu-item>
`
: ""}
: nothing}
${item.disabled_by && services.length
? html`<ha-md-menu-item
href=${services.length === 1
@ -832,7 +865,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
)}
<ha-icon-next slot="end"></ha-icon-next>
</ha-md-menu-item> `
: ""}
: nothing}
${item.disabled_by && entities.length
? html`
<ha-md-menu-item
@ -849,7 +882,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<ha-icon-next slot="end"></ha-icon-next>
</ha-md-menu-item>
`
: ""}
: nothing}
${!item.disabled_by &&
RECOVERABLE_STATES.includes(item.state) &&
item.supports_unload &&
@ -886,7 +919,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
)}
</ha-md-menu-item>
`
: ""}
: nothing}
${!item.disabled_by &&
item.supports_reconfigure &&
item.source !== "system"
@ -1424,6 +1457,9 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
margin-top: 32px;
margin-bottom: 32px;
}
.card-content {
padding: 16px 0 8px;
}
.column {
width: 33%;
flex-grow: 1;
@ -1471,12 +1507,45 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
max-width: 200px;
max-height: 100px;
}
ha-alert {
display: block;
margin-top: 4px;
@keyframes shimmer {
100% {
mask-position: left;
}
ha-alert:first-of-type {
margin-top: 16px;
}
.integration-info {
display: flex;
align-items: center;
gap: 20px;
padding: 0 20px;
min-height: 48px;
}
.integration-info ha-svg-icon {
min-width: 24px;
color: var(--mdc-theme-text-icon-on-background);
}
.integration-info.warn ha-svg-icon {
color: var(--warning-color);
}
.integration-info.info ha-svg-icon {
color: var(--info-color);
}
.quality-scale ha-svg-icon {
mask: linear-gradient(-60deg, #000 30%, #0005, #000 70%) right/350%
100%;
animation: shimmer 2.5s infinite;
}
ha-svg-icon.bronze-medal {
color: #cd7f32;
}
ha-svg-icon.silver-medal {
color: silver;
}
ha-svg-icon.gold-medal {
color: gold;
}
ha-svg-icon.platinum-medal {
color: #d9d9d9;
}
ha-md-list-item {
position: relative;

View File

@ -4520,7 +4520,12 @@
"failed_unload": "Failed to unload",
"setup_in_progress": "Initializing"
},
"open_configuration_url": "Visit device"
"open_configuration_url": "Visit device",
"bronze_quality": "Bronze on our {quality_scale}",
"silver_quality": "Silver on our {quality_scale}",
"gold_quality": "Gold on our {quality_scale}",
"platinum_quality": "Platinum on our {quality_scale}",
"quality_scale": "quality scale"
},
"config_flow": {
"success": "Success",