mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-15 13:26:34 +00:00
Integration Quality Scale indicator (#23015)
This commit is contained in:
parent
f54bb20fef
commit
bc195c61cc
@ -38,7 +38,7 @@ export interface IntegrationManifest {
|
|||||||
homekit?: { models: string[] };
|
homekit?: { models: string[] };
|
||||||
integration_type?: IntegrationType;
|
integration_type?: IntegrationType;
|
||||||
loggers?: string[];
|
loggers?: string[];
|
||||||
quality_scale?: "gold" | "internal" | "platinum" | "silver";
|
quality_scale?: "bronze" | "gold" | "internal" | "platinum" | "silver";
|
||||||
iot_class:
|
iot_class:
|
||||||
| "assumed_state"
|
| "assumed_state"
|
||||||
| "cloud_polling"
|
| "cloud_polling"
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
mdiBug,
|
mdiBug,
|
||||||
mdiBugPlay,
|
mdiBugPlay,
|
||||||
mdiBugStop,
|
mdiBugStop,
|
||||||
mdiCloud,
|
|
||||||
mdiCog,
|
mdiCog,
|
||||||
mdiDelete,
|
mdiDelete,
|
||||||
mdiDevices,
|
mdiDevices,
|
||||||
@ -14,6 +13,7 @@ import {
|
|||||||
mdiDownload,
|
mdiDownload,
|
||||||
mdiFileCodeOutline,
|
mdiFileCodeOutline,
|
||||||
mdiHandExtendedOutline,
|
mdiHandExtendedOutline,
|
||||||
|
mdiMedal,
|
||||||
mdiOpenInNew,
|
mdiOpenInNew,
|
||||||
mdiPackageVariant,
|
mdiPackageVariant,
|
||||||
mdiPlayCircleOutline,
|
mdiPlayCircleOutline,
|
||||||
@ -23,6 +23,8 @@ import {
|
|||||||
mdiRenameBox,
|
mdiRenameBox,
|
||||||
mdiShapeOutline,
|
mdiShapeOutline,
|
||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
|
mdiTrophy,
|
||||||
|
mdiWeb,
|
||||||
mdiWrench,
|
mdiWrench,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
@ -338,41 +340,72 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
${this._manifest?.version != null
|
${this._manifest?.version != null
|
||||||
? html`<div class="version">${this._manifest.version}</div>`
|
? html`<div class="version">${this._manifest.version}</div>`
|
||||||
: nothing}
|
: 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
|
${this._manifest?.is_built_in === false
|
||||||
? html`<ha-alert alert-type="warning"
|
? html`<div class="integration-info warn">
|
||||||
><ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="icon"
|
class="warning"
|
||||||
path=${mdiPackageVariant}
|
path=${mdiPackageVariant}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.integrations.config_entry.custom_integration"
|
"ui.panel.config.integrations.config_entry.custom_integration"
|
||||||
)}</ha-alert
|
)}
|
||||||
>`
|
</div>`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._manifest?.iot_class?.startsWith("cloud_")
|
${this._manifest?.iot_class?.startsWith("cloud_")
|
||||||
? html`<ha-alert
|
? html`<div class="integration-info">
|
||||||
><ha-svg-icon slot="icon" path=${mdiCloud}></ha-svg-icon
|
<ha-svg-icon .path=${mdiWeb}></ha-svg-icon>
|
||||||
>${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.integrations.config_entry.depends_on_cloud"
|
"ui.panel.config.integrations.config_entry.depends_on_cloud"
|
||||||
)}</ha-alert
|
)}
|
||||||
>`
|
</div>`
|
||||||
: ""}
|
: nothing}
|
||||||
${normalEntries.length === 0 &&
|
${normalEntries.length === 0 &&
|
||||||
this._manifest &&
|
this._manifest &&
|
||||||
!this._manifest.config_flow &&
|
!this._manifest.config_flow &&
|
||||||
this.hass.config.components.find(
|
this.hass.config.components.find(
|
||||||
(comp) => comp.split(".")[0] === this.domain
|
(comp) => comp.split(".")[0] === this.domain
|
||||||
)
|
)
|
||||||
? html`<ha-alert alert-type="info"
|
? html`<div class="integration-info info">
|
||||||
><ha-svg-icon
|
<ha-svg-icon path=${mdiFileCodeOutline}></ha-svg-icon
|
||||||
slot="icon"
|
|
||||||
path=${mdiFileCodeOutline}
|
|
||||||
></ha-svg-icon
|
|
||||||
>${this.hass.localize(
|
>${this.hass.localize(
|
||||||
"ui.panel.config.integrations.config_entry.no_config_flow"
|
"ui.panel.config.integrations.config_entry.no_config_flow"
|
||||||
)}</ha-alert
|
)}
|
||||||
>`
|
</div>`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
@ -398,7 +431,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<ha-icon-next slot="meta"></ha-icon-next>
|
<ha-icon-next slot="meta"></ha-icon-next>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</a>`
|
</a>`
|
||||||
: ""}
|
: nothing}
|
||||||
${numberOfEntities > 0
|
${numberOfEntities > 0
|
||||||
? html`<a
|
? html`<a
|
||||||
href=${`/config/entities?historyBack=1&domain=${this.domain}`}
|
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-icon-next slot="meta"></ha-icon-next>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</a>`
|
</a>`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._manifest
|
${this._manifest
|
||||||
? html`<a
|
? html`<a
|
||||||
href=${this._manifest.is_built_in
|
href=${this._manifest.is_built_in
|
||||||
@ -441,7 +474,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</a>`
|
</a>`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._manifest &&
|
${this._manifest &&
|
||||||
(this._manifest.is_built_in || this._manifest.issue_tracker)
|
(this._manifest.is_built_in || this._manifest.issue_tracker)
|
||||||
? html`<a
|
? html`<a
|
||||||
@ -463,7 +496,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</a>`
|
</a>`
|
||||||
: ""}
|
: nothing}
|
||||||
${this._logInfo
|
${this._logInfo
|
||||||
? html`<ha-list-item
|
? html`<ha-list-item
|
||||||
@request-selected=${this._logInfo.level ===
|
@request-selected=${this._logInfo.level ===
|
||||||
@ -489,7 +522,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
: mdiBugPlay}
|
: mdiBugPlay}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</ha-list-item>`
|
</ha-list-item>`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</div>
|
</div>
|
||||||
@ -517,7 +550,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
</ha-md-list>
|
</ha-md-list>
|
||||||
</ha-card>`
|
</ha-card>`
|
||||||
: ""}
|
: nothing}
|
||||||
${attentionFlows.length || attentionEntries.length
|
${attentionFlows.length || attentionEntries.length
|
||||||
? html`<ha-card>
|
? html`<ha-card>
|
||||||
<h1 class="card-header">
|
<h1 class="card-header">
|
||||||
@ -562,11 +595,11 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
></ha-md-divider>`
|
></ha-md-divider>`
|
||||||
: ""} `
|
: nothing} `
|
||||||
)}
|
)}
|
||||||
</ha-md-list>
|
</ha-md-list>
|
||||||
</ha-card>`
|
</ha-card>`
|
||||||
: ""}
|
: nothing}
|
||||||
|
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<h1 class="card-header">
|
<h1 class="card-header">
|
||||||
@ -602,7 +635,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
></ha-md-divider>`
|
></ha-md-divider>`
|
||||||
: ""} `
|
: nothing}`
|
||||||
)}
|
)}
|
||||||
</ha-md-list>
|
</ha-md-list>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
@ -762,11 +795,11 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<div>
|
<div>
|
||||||
${this.hass.localize(...stateText)}${stateTextExtra
|
${this.hass.localize(...stateText)}${stateTextExtra
|
||||||
? html`: ${stateTextExtra}`
|
? html`: ${stateTextExtra}`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
${item.disabled_by === "user"
|
${item.disabled_by === "user"
|
||||||
? html`<ha-button unelevated slot="end" @click=${this._handleEnable}>
|
? html`<ha-button unelevated slot="end" @click=${this._handleEnable}>
|
||||||
@ -793,7 +826,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
</ha-button>
|
</ha-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
<ha-md-button-menu positioning="popover" slot="end">
|
<ha-md-button-menu positioning="popover" slot="end">
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
@ -815,7 +848,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<ha-icon-next slot="end"></ha-icon-next>
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${item.disabled_by && services.length
|
${item.disabled_by && services.length
|
||||||
? html`<ha-md-menu-item
|
? html`<ha-md-menu-item
|
||||||
href=${services.length === 1
|
href=${services.length === 1
|
||||||
@ -832,7 +865,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
<ha-icon-next slot="end"></ha-icon-next>
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
</ha-md-menu-item> `
|
</ha-md-menu-item> `
|
||||||
: ""}
|
: nothing}
|
||||||
${item.disabled_by && entities.length
|
${item.disabled_by && entities.length
|
||||||
? html`
|
? html`
|
||||||
<ha-md-menu-item
|
<ha-md-menu-item
|
||||||
@ -849,7 +882,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
<ha-icon-next slot="end"></ha-icon-next>
|
<ha-icon-next slot="end"></ha-icon-next>
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${!item.disabled_by &&
|
${!item.disabled_by &&
|
||||||
RECOVERABLE_STATES.includes(item.state) &&
|
RECOVERABLE_STATES.includes(item.state) &&
|
||||||
item.supports_unload &&
|
item.supports_unload &&
|
||||||
@ -886,7 +919,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
`
|
`
|
||||||
: ""}
|
: nothing}
|
||||||
${!item.disabled_by &&
|
${!item.disabled_by &&
|
||||||
item.supports_reconfigure &&
|
item.supports_reconfigure &&
|
||||||
item.source !== "system"
|
item.source !== "system"
|
||||||
@ -1424,6 +1457,9 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
}
|
}
|
||||||
|
.card-content {
|
||||||
|
padding: 16px 0 8px;
|
||||||
|
}
|
||||||
.column {
|
.column {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
@ -1471,12 +1507,45 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
|||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
max-height: 100px;
|
max-height: 100px;
|
||||||
}
|
}
|
||||||
ha-alert {
|
|
||||||
display: block;
|
@keyframes shimmer {
|
||||||
margin-top: 4px;
|
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 {
|
ha-md-list-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -4520,7 +4520,12 @@
|
|||||||
"failed_unload": "Failed to unload",
|
"failed_unload": "Failed to unload",
|
||||||
"setup_in_progress": "Initializing"
|
"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": {
|
"config_flow": {
|
||||||
"success": "Success",
|
"success": "Success",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user