ha-frontend/src/components/ha-cards.html

357 lines
8.1 KiB
HTML
Raw Normal View History

2015-08-23 10:26:31 +02:00
<link rel="import" href="../../bower_components/polymer/polymer.html">
2016-08-02 18:06:22 +02:00
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
2015-08-30 04:10:16 +02:00
<link rel="import" href="./ha-demo-badge.html">
2015-08-23 10:26:31 +02:00
<link rel="import" href="../cards/ha-badges-card.html">
2016-02-17 08:26:56 +01:00
<link rel="import" href="../cards/ha-card-chooser.html">
2015-08-23 10:26:31 +02:00
2016-01-25 08:58:10 +01:00
<dom-module id="ha-cards">
2016-07-19 10:19:44 +02:00
<template>
<style is="custom-style" include="iron-flex iron-flex-factors"></style>
<style>
:host {
display: block;
2016-07-31 09:32:49 +02:00
padding-top: 8px;
2016-07-19 10:19:44 +02:00
padding-right: 8px;
}
2015-08-23 10:26:31 +02:00
2016-07-19 10:19:44 +02:00
.badges {
font-size: 85%;
text-align: center;
}
2015-12-05 10:09:51 +01:00
2016-07-19 10:19:44 +02:00
.column {
max-width: 500px;
overflow-x: hidden;
2015-12-05 10:09:51 +01:00
}
.zone-card {
2016-07-19 10:19:44 +02:00
margin-left: 8px;
margin-bottom: 8px;
2015-12-05 10:09:51 +01:00
}
2015-12-15 08:52:06 +01:00
2016-07-19 10:19:44 +02:00
@media (max-width: 500px) {
:host {
padding-right: 0;
}
.zone-card {
margin-left: 0;
}
2015-12-15 08:52:06 +01:00
}
2016-07-19 10:19:44 +02:00
@media (max-width: 599px) {
.column {
max-width: 600px;
}
}
</style>
2015-08-23 10:26:31 +02:00
<div class='main'>
2016-04-28 16:19:27 +02:00
<template is='dom-if' if='[[cards.badges]]'>
2015-08-23 10:26:31 +02:00
<div class='badges'>
2016-04-28 16:19:27 +02:00
<template is='dom-if' if='[[cards.demo]]'>
2015-08-30 04:10:16 +02:00
<ha-demo-badge></ha-demo-badge>
</template>
2016-05-28 10:32:39 +02:00
<ha-badges-card states='[[cards.badges]]' hass='[[hass]]'></ha-badges-card>
2015-08-23 10:26:31 +02:00
</div>
</template>
2016-02-17 08:26:56 +01:00
2016-04-11 00:17:07 +02:00
<div class='horizontal layout center-justified'>
2016-04-28 16:19:27 +02:00
<template is='dom-repeat' items='[[cards.columns]]' as='column'>
2016-02-17 08:26:56 +01:00
<div class='column flex-1'>
<template is='dom-repeat' items='[[column]]' as='card'>
<div class='zone-card'>
2016-05-28 10:32:39 +02:00
<ha-card-chooser card-data='[[card]]' hass='[[hass]]'
2016-03-31 17:51:27 +02:00
></ha-card-chooser>
2016-02-17 08:26:56 +01:00
</div>
</template>
</div>
2015-08-23 10:26:31 +02:00
</template>
</div>
</template>
</dom-module>
2016-07-18 08:18:48 +02:00
<script>
(function () {
'use strict';
2016-11-27 02:43:55 +01:00
2016-07-18 08:18:48 +02:00
// mapping domain to size of the card.
var DOMAINS_WITH_CARD = {
camera: 4,
media_player: 3,
persistent_notification: 0,
weather: 4,
2016-07-18 08:18:48 +02:00
};
// 4 types:
// badges: 0 .. 10
// before groups < 0
// groups: X
// rest: 100
2016-07-18 08:18:48 +02:00
var PRIORITY = {
// before groups < 0
2016-07-18 08:18:48 +02:00
configurator: -20,
persistent_notification: -15,
// badges have priority >= 0
2016-07-18 08:18:48 +02:00
updater: 0,
sun: 1,
device_tracker: 2,
alarm_control_panel: 3,
sensor: 5,
binary_sensor: 6,
};
function getPriority(domain) {
return (domain in PRIORITY) ? PRIORITY[domain] : 100;
}
function sortPriority(domainA, domainB) {
return domainA.priority - domainB.priority;
2016-07-18 08:18:48 +02:00
}
function entitySortBy(entityA, entityB) {
var nameA = (entityA.attributes.friendly_name ||
entityA.entity_id).toLowerCase();
var nameB = (entityB.attributes.friendly_name ||
entityB.entity_id).toLowerCase();
if (nameA < nameB) {
return -1;
}
if (nameB > nameA) {
return 1;
}
return 0;
2016-07-18 08:18:48 +02:00
}
function iterateDomainSorted(collection, func) {
Object.keys(collection)
.map(function (key) { return collection[key]; })
.sort(sortPriority)
.forEach(function (domain) {
domain.states.sort(entitySortBy);
func(domain);
});
}
var computeDomain = window.hassUtil.computeDomain;
2016-07-18 08:18:48 +02:00
Polymer({
is: 'ha-cards',
properties: {
hass: {
type: Object,
},
showIntroduction: {
type: Boolean,
value: false,
},
columns: {
type: Number,
value: 2,
},
states: {
type: Object,
},
2016-07-31 22:04:01 +02:00
panelVisible: {
type: Boolean,
},
viewVisible: {
type: Boolean,
value: false,
},
2016-07-18 08:18:48 +02:00
cards: {
type: Object,
},
},
observers: [
2016-07-31 22:04:01 +02:00
'updateCards(columns, states, showIntroduction, panelVisible, viewVisible)',
2016-07-18 08:18:48 +02:00
],
2016-11-27 02:43:55 +01:00
updateCards: function (columns, states, showIntroduction, panelVisible, viewVisible) {
/* eslint-disable no-console */
2016-07-31 22:04:01 +02:00
if (!panelVisible || !viewVisible) {
return;
}
2016-07-18 08:18:48 +02:00
this.debounce(
'updateCards', function () {
// Things might have changed since it got scheduled.
if (this.panelVisible && this.viewVisible) {
this.cards = this.computeCards(columns, states, showIntroduction);
}
}.bind(this), 10);
2016-07-18 08:18:48 +02:00
},
computeCards: function (columns, states, showIntroduction) {
var hass = this.hass;
var cards = {
demo: false,
badges: [],
columns: [],
};
var entityCount = [];
var i;
for (i = 0; i < columns; i++) {
cards.columns.push([]);
entityCount.push(0);
}
// Find column with < 5 entities, else column with lowest count
function getIndex(size) {
var minIndex = 0;
for (i = minIndex; i < entityCount.length; i++) {
if (entityCount[i] < 5) {
minIndex = i;
break;
}
if (entityCount[i] < entityCount[minIndex]) {
minIndex = i;
}
}
entityCount[minIndex] += size;
return minIndex;
}
if (showIntroduction) {
cards.columns[getIndex(5)].push({
hass: hass,
cardType: 'introduction',
showHideInstruction: states.size > 0 && !window.HASS_DEMO,
2016-07-18 08:18:48 +02:00
});
}
function addEntitiesCard(name, entities, groupEntity) {
var owncard;
var other;
var size;
var curIndex;
if (entities.length === 0) return;
owncard = [];
other = [];
size = 0;
entities.forEach(function (entity) {
var domain = computeDomain(entity);
if (domain in DOMAINS_WITH_CARD) {
2016-07-18 08:18:48 +02:00
owncard.push(entity);
size += DOMAINS_WITH_CARD[domain];
2016-07-18 08:18:48 +02:00
} else {
other.push(entity);
size++;
}
});
// Add 1 to the size if we're rendering entities card
size += other.length > 1;
curIndex = getIndex(size);
if (other.length > 0) {
cards.columns[curIndex].push({
hass: hass,
cardType: 'entities',
states: other,
groupEntity: groupEntity || false,
});
}
owncard.forEach(function (entity) {
cards.columns[curIndex].push({
hass: hass,
cardType: computeDomain(entity),
2016-07-18 08:18:48 +02:00
stateObj: entity,
});
});
}
var sorted = window.HAWS.splitByGroups(states);
2016-07-18 08:18:48 +02:00
var badgesColl = {};
var beforeGroupColl = {};
var afterGroupedColl = {};
2016-07-18 08:18:48 +02:00
Object.keys(sorted.ungrouped).forEach(function (key) {
var state = sorted.ungrouped[key];
var domain = computeDomain(state);
2016-07-18 08:18:48 +02:00
if (domain === 'a') {
cards.demo = true;
return;
2016-07-18 08:18:48 +02:00
}
var priority = getPriority(domain);
var coll;
if (priority < 0) {
coll = beforeGroupColl;
} else if (priority < 10) {
coll = badgesColl;
} else {
coll = afterGroupedColl;
}
if (!(domain in coll)) {
coll[domain] = {
domain: domain,
priority: priority,
states: [],
};
}
coll[domain].states.push(state);
});
iterateDomainSorted(badgesColl, function (domain) {
cards.badges.push.apply(cards.badges, domain.states);
});
iterateDomainSorted(beforeGroupColl, function (domain) {
addEntitiesCard(domain.domain, domain.states);
});
sorted.groups.forEach(function (groupState) {
var entities = window.HAWS.getGroupEntities(states, groupState);
addEntitiesCard(
groupState.entity_id,
Object.keys(entities).map(function (key) {
return entities[key];
}),
groupState
);
});
iterateDomainSorted(afterGroupedColl, function (domain) {
addEntitiesCard(domain.domain, domain.states);
});
2016-07-18 08:18:48 +02:00
// Remove empty columns
cards.columns = cards.columns.filter(function (val) {
return val.length > 0;
});
return cards;
},
});
}());
</script>