diff --git a/src/panels/config/config-entries/ha-ce-entities-card.js b/src/panels/config/config-entries/ha-ce-entities-card.js
new file mode 100644
index 0000000000..ec2af9ff97
--- /dev/null
+++ b/src/panels/config/config-entries/ha-ce-entities-card.js
@@ -0,0 +1,74 @@
+import '@polymer/paper-item/paper-icon-item.js';
+import '@polymer/paper-item/paper-item-body.js';
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../../layouts/hass-subpage.js';
+
+import EventsMixin from '../../../mixins/events-mixin.js';
+import computeStateName from '../../../common/entity/compute_state_name.js';
+import '../../../components/entity/state-badge.js';
+
+function computeEntityName(hass, entity) {
+ if (entity.name) return entity.name;
+ const state = hass.states[entity.entity_id];
+ return state ? computeStateName(state) : null;
+}
+
+/*
+ * @appliesMixin EventsMixin
+ */
+class HaDeviceCard extends EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
+
+
+
+
+
+
+ [[_computeEntityName(entity, hass)]]
+ [[entity.entity_id]]
+
+
+
+
+ `;
+ }
+
+ static get properties() {
+ return {
+ heading: String,
+ entities: Array,
+ hass: Object,
+ };
+ }
+
+ _computeStateObj(entity, hass) {
+ return hass.states[entity.entity_id];
+ }
+
+ _computeEntityName(entity, hass) {
+ return computeEntityName(hass, entity) || '(entity unavailable)';
+ }
+
+ _openMoreInfo(ev) {
+ this.fire('hass-more-info', { entityId: ev.model.entity.entity_id });
+ }
+}
+
+customElements.define('ha-ce-entities-card', HaDeviceCard);
diff --git a/src/panels/config/config-entries/ha-config-entry-page.js b/src/panels/config/config-entries/ha-config-entry-page.js
index f2c8e70d80..47a553f0dc 100644
--- a/src/panels/config/config-entries/ha-config-entry-page.js
+++ b/src/panels/config/config-entries/ha-config-entry-page.js
@@ -8,6 +8,7 @@ import '../../../components/entity/state-badge.js';
import compare from '../../../common/string/compare.js';
import './ha-device-card.js';
+import './ha-ce-entities-card.js';
import EventsMixin from '../../../mixins/events-mixin.js';
import NavigateMixin from '../../../mixins/navigate-mixin.js';
@@ -19,9 +20,8 @@ class HaConfigEntryPage extends NavigateMixin(EventsMixin(PolymerElement)) {
display: flex;
flex-wrap: wrap;
padding: 4px;
- justify-content: center;
}
- ha-device-card {
+ ha-device-card, ha-ce-entities-card {
flex: 1;
min-width: 300px;
max-width: 300px;
@@ -43,10 +43,10 @@ class HaConfigEntryPage extends NavigateMixin(EventsMixin(PolymerElement)) {
on-click='_removeEntry'
>
-
+
This integration has no devices.
-
+
+
+
+
`;
@@ -68,11 +75,20 @@ class HaConfigEntryPage extends NavigateMixin(EventsMixin(PolymerElement)) {
value: null,
},
- configEntryDevices: {
+ _configEntryDevices: {
type: Array,
computed: '_computeConfigEntryDevices(configEntry, devices)'
},
+ /**
+ * All entity registry entries for this config entry that do not belong
+ * to a device.
+ */
+ _noDeviceEntities: {
+ type: Array,
+ computed: '_computeNoDeviceEntities(configEntry, entities)',
+ },
+
/**
* Device registry entries
*/
@@ -98,6 +114,15 @@ class HaConfigEntryPage extends NavigateMixin(EventsMixin(PolymerElement)) {
|| compare(dev1.name, dev2.name));
}
+ _computeNoDeviceEntities(configEntry, entities) {
+ if (!entities) return [];
+ return entities.filter(ent => !ent.device_id && ent.config_entry_id === configEntry.entry_id);
+ }
+
+ _computeIsEmpty(configEntryDevices, noDeviceEntities) {
+ return configEntryDevices.length === 0 && noDeviceEntities.length === 0;
+ }
+
_removeEntry() {
if (!confirm('Are you sure you want to delete this integration?')) return;