mirror of
https://github.com/beestat/app.git
synced 2025-05-24 02:14:03 -04:00
727 lines
22 KiB
JavaScript
727 lines
22 KiB
JavaScript
/**
|
||
* Floor plan editor.
|
||
*
|
||
* @param {number} thermostat_id
|
||
*/
|
||
beestat.component.card.floor_plan_editor = function(thermostat_id) {
|
||
const self = this;
|
||
|
||
this.thermostat_id_ = thermostat_id;
|
||
|
||
// Whether or not to show the editor when loading.
|
||
this.show_editor_ = beestat.floor_plan.get_bounding_box(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
).x === Infinity;
|
||
|
||
/* const change_function = beestat.debounce(function() {
|
||
// todo replace these with (if entity set active false?)
|
||
delete self.state_.active_group;
|
||
|
||
self.rerender();
|
||
|
||
// Center the content if the floor plan changed.
|
||
if (self.floor_plan_ !== undefined) {
|
||
self.floor_plan_.center_content();
|
||
}
|
||
}, 10);
|
||
|
||
beestat.dispatcher.addEventListener(
|
||
'setting.visualize.floor_plan_id',
|
||
change_function
|
||
);*/
|
||
|
||
beestat.component.card.apply(this, arguments);
|
||
|
||
// Snapping initial
|
||
if (this.state_.snapping === undefined) {
|
||
this.state_.snapping = true;
|
||
}
|
||
|
||
// The first time this component renders center the content.
|
||
this.addEventListener('render', function() {
|
||
if (this.floor_plan_ !== undefined) {
|
||
self.floor_plan_.center_content();
|
||
self.removeEventListener('render');
|
||
}
|
||
});
|
||
};
|
||
beestat.extend(beestat.component.card.floor_plan_editor, beestat.component.card);
|
||
|
||
/**
|
||
* Decorate.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_contents_ = function(parent) {
|
||
const self = this;
|
||
|
||
const floor_plan = beestat.cache.floor_plan[beestat.setting('visualize.floor_plan_id')];
|
||
|
||
// Set group ids if they are not set.
|
||
floor_plan.data.groups.forEach(function(group) {
|
||
if (group.group_id === undefined) {
|
||
group.group_id = window.crypto.randomUUID();
|
||
}
|
||
});
|
||
|
||
/**
|
||
* If there is an active_group_id, override whatever the current active
|
||
* group is. Used for undo/redo.
|
||
*/
|
||
if (this.state_.active_group_id !== undefined) {
|
||
for (let i = 0; i < floor_plan.data.groups.length; i++) {
|
||
if (floor_plan.data.groups[i].group_id === this.state_.active_group_id) {
|
||
this.state_.active_group = floor_plan.data.groups[i];
|
||
delete this.state_.active_group_id;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If there is no active group, set it to best guess of ground floor.
|
||
if (this.state_.active_group === undefined) {
|
||
let closest_distance = Infinity;
|
||
let closest_group;
|
||
floor_plan.data.groups.forEach(function(group) {
|
||
if (Math.abs(group.elevation) < closest_distance) {
|
||
closest_group = group;
|
||
closest_distance = Math.abs(group.elevation);
|
||
}
|
||
});
|
||
this.state_.active_group = closest_group;
|
||
}
|
||
|
||
this.floor_plan_tile_ = new beestat.component.tile.floor_plan(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
)
|
||
.set_background_color(beestat.style.color.lightblue.base)
|
||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||
.set_text_color('#fff')
|
||
.set_display('block')
|
||
.addEventListener('click', function() {
|
||
self.show_editor_ = !self.show_editor_;
|
||
self.rerender();
|
||
})
|
||
.render(parent);
|
||
|
||
// Decorate everything.
|
||
if (this.show_editor_ === true) {
|
||
const drawing_pane_container = $.createElement('div');
|
||
drawing_pane_container.style({
|
||
'margin-top': beestat.style.size.gutter,
|
||
'position': 'relative',
|
||
'overflow-x': 'hidden'
|
||
});
|
||
parent.appendChild(drawing_pane_container);
|
||
this.decorate_drawing_pane_(drawing_pane_container);
|
||
|
||
this.info_pane_container_ = $.createElement('div')
|
||
.style('margin-top', beestat.style.size.gutter / 2);
|
||
parent.appendChild(this.info_pane_container_);
|
||
this.decorate_info_pane_(this.info_pane_container_);
|
||
|
||
// Help container
|
||
if (beestat.floor_plan.get_area(beestat.setting('visualize.floor_plan_id')) === 0) {
|
||
const help_container = document.createElement('div');
|
||
Object.assign(help_container.style, {
|
||
'position': 'absolute',
|
||
'left': '65px',
|
||
'top': '59px'
|
||
});
|
||
drawing_pane_container.appendChild(help_container);
|
||
|
||
this.helper_tile_ = new beestat.component.tile()
|
||
.set_text('Start by adding a room')
|
||
.set_shadow(false)
|
||
.set_background_color(beestat.style.color.green.base)
|
||
.set_text_color('#fff')
|
||
.set_type('pill')
|
||
.set_size('small')
|
||
.set_icon('arrow_left')
|
||
.render($(help_container));
|
||
}
|
||
}
|
||
|
||
const expand_container = document.createElement('div');
|
||
Object.assign(expand_container.style, {
|
||
'position': 'absolute',
|
||
'right': '28px',
|
||
'top': '70px'
|
||
});
|
||
parent.appendChild(expand_container);
|
||
|
||
new beestat.component.tile()
|
||
.set_icon(this.show_editor_ === true ? 'chevron_up' : 'chevron_down')
|
||
.set_size('small')
|
||
.set_shadow(false)
|
||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||
.set_text_color('#fff')
|
||
.addEventListener('click', function() {
|
||
self.show_editor_ = !self.show_editor_;
|
||
self.rerender();
|
||
})
|
||
.render($(expand_container));
|
||
};
|
||
|
||
/**
|
||
* Decorate the drawing pane.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_drawing_pane_ = function(parent) {
|
||
const self = this;
|
||
|
||
// Dispose existing SVG to remove any global listeners.
|
||
if (this.floor_plan_ !== undefined) {
|
||
this.floor_plan_.dispose();
|
||
}
|
||
|
||
// Create and render a new SVG component.
|
||
this.floor_plan_ = new beestat.component.floor_plan(
|
||
beestat.setting('visualize.floor_plan_id'),
|
||
this.state_
|
||
);
|
||
|
||
this.floor_plan_.render(parent);
|
||
|
||
setTimeout(function() {
|
||
if (parent.getBoundingClientRect().width > 0) {
|
||
self.floor_plan_.set_width(parent.getBoundingClientRect().width);
|
||
}
|
||
}, 0);
|
||
|
||
beestat.dispatcher.removeEventListener('resize.floor_plan_editor');
|
||
beestat.dispatcher.addEventListener('resize.floor_plan_editor', function() {
|
||
self.floor_plan_.set_width(parent.getBoundingClientRect().width);
|
||
});
|
||
|
||
// Rerender when stuff happens
|
||
this.floor_plan_.addEventListener('add_room', function() {
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
});
|
||
this.floor_plan_.addEventListener('remove_room', function() {
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
});
|
||
this.floor_plan_.addEventListener('remove_point', function() {
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
});
|
||
this.floor_plan_.addEventListener('undo', function() {
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
});
|
||
this.floor_plan_.addEventListener('redo', function() {
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
});
|
||
this.floor_plan_.addEventListener('change_group', self.rerender.bind(this));
|
||
|
||
const group_below = this.floor_plan_.get_group_below(this.state_.active_group);
|
||
if (group_below !== undefined) {
|
||
group_below.rooms.forEach(function(room) {
|
||
const room_entity = new beestat.component.floor_plan_entity.room(self.floor_plan_, self.state_)
|
||
.set_enabled(false)
|
||
.set_room(room)
|
||
.set_group(self.state_.active_group);
|
||
room_entity.render(self.floor_plan_.get_g());
|
||
});
|
||
}
|
||
|
||
// Loop over the rooms in this group and add them.
|
||
let active_room_entity;
|
||
this.state_.active_group.rooms.forEach(function(room) {
|
||
const room_entity = new beestat.component.floor_plan_entity.room(self.floor_plan_, self.state_)
|
||
.set_room(room)
|
||
.set_group(self.state_.active_group);
|
||
|
||
// Update the GUI and save when a room changes.
|
||
room_entity.addEventListener('update', function() {
|
||
self.floor_plan_.update_infobox();
|
||
self.update_info_pane_();
|
||
self.update_floor_plan_tile_();
|
||
self.update_floor_plan_();
|
||
});
|
||
|
||
// Update GUI when a room is selected.
|
||
room_entity.addEventListener('activate', function() {
|
||
self.floor_plan_.update_infobox();
|
||
self.floor_plan_.update_toolbar();
|
||
self.update_info_pane_();
|
||
self.update_floor_plan_tile_();
|
||
});
|
||
|
||
// Update GUI when a room is deselected.
|
||
room_entity.addEventListener('inactivate', function() {
|
||
self.floor_plan_.update_infobox();
|
||
self.floor_plan_.update_toolbar();
|
||
self.update_info_pane_();
|
||
self.update_floor_plan_tile_();
|
||
});
|
||
|
||
/**
|
||
* If there is currently an active room, use it to match to the newly
|
||
* created room entities and then store it. After this loop is done
|
||
* activate it to avoid other rooms getting written on top. Also delete
|
||
* the active room from the state or it will needlessly be inactivated in
|
||
* the set_active function.
|
||
*/
|
||
if (
|
||
self.state_.active_room_entity !== undefined &&
|
||
room.room_id === self.state_.active_room_entity.get_room().room_id
|
||
) {
|
||
delete self.state_.active_room_entity;
|
||
active_room_entity = room_entity;
|
||
}
|
||
|
||
// Render the room and save to the list of current entities.
|
||
room_entity.render(self.floor_plan_.get_g());
|
||
});
|
||
|
||
if (active_room_entity !== undefined) {
|
||
active_room_entity.set_active(true);
|
||
}
|
||
|
||
/**
|
||
* If there was an active room, defer to adding it last so it ends up on
|
||
* top. The set_active function doesn't do anything if the room isn't
|
||
* rendered otherwise.
|
||
*/
|
||
if (this.state_.active_room_entity !== undefined) {
|
||
this.state_.active_room_entity.render(this.floor_plan_.get_g());
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Decorate the info pane.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_info_pane_ = function(parent) {
|
||
if (this.state_.active_room_entity !== undefined) {
|
||
this.decorate_info_pane_room_(parent);
|
||
} else {
|
||
this.decorate_info_pane_floor_(parent);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Decorate the info pane for a floor.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_info_pane_floor_ = function(parent) {
|
||
const self = this;
|
||
|
||
const grid = $.createElement('div')
|
||
.style({
|
||
'display': 'grid',
|
||
'grid-template-columns': 'repeat(auto-fit, minmax(150px, 1fr))',
|
||
'column-gap': beestat.style.size.gutter
|
||
});
|
||
parent.appendChild(grid);
|
||
|
||
let div;
|
||
|
||
// Group Name
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const name_input = new beestat.component.input.text()
|
||
.set_label('Floor Name')
|
||
.set_placeholder('Unnamed Floor')
|
||
.set_width('100%')
|
||
.set_maxlength('50')
|
||
.set_requirements({
|
||
'required': true
|
||
})
|
||
.render(div);
|
||
|
||
if (this.state_.active_group.name !== undefined) {
|
||
name_input.set_value(this.state_.active_group.name);
|
||
}
|
||
|
||
name_input.addEventListener('input', function() {
|
||
self.state_.active_group.name = name_input.get_value();
|
||
self.floor_plan_.update_infobox();
|
||
});
|
||
name_input.addEventListener('change', function() {
|
||
self.state_.active_group.name = name_input.get_value();
|
||
self.update_floor_plan_();
|
||
});
|
||
|
||
// Elevation
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const elevation_input = new beestat.component.input.text()
|
||
.set_label('Elevation (feet)')
|
||
.set_placeholder(this.state_.active_group.elevation / 12)
|
||
.set_value(this.state_.active_group.elevation / 12 || '')
|
||
.set_width('100%')
|
||
.set_maxlength('5')
|
||
.set_requirements({
|
||
'type': 'integer',
|
||
'required': true
|
||
})
|
||
.render(div);
|
||
|
||
elevation_input.addEventListener('change', function() {
|
||
if (elevation_input.meets_requirements() === true) {
|
||
self.state_.active_group.elevation = elevation_input.get_value() * 12;
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
} else {
|
||
elevation_input.set_value(self.state_.active_group.elevation);
|
||
}
|
||
});
|
||
|
||
// Ceiling Height
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const height_input = new beestat.component.input.text()
|
||
.set_label('Ceiling Height (feet)')
|
||
.set_placeholder(this.state_.active_group.height / 12)
|
||
.set_value(this.state_.active_group.height / 12 || '')
|
||
.set_width('100%')
|
||
.set_maxlength('4')
|
||
.set_requirements({
|
||
'type': 'integer',
|
||
'min_value': 1,
|
||
'required': true
|
||
})
|
||
.render(div);
|
||
|
||
height_input.addEventListener('change', function() {
|
||
if (height_input.meets_requirements() === true) {
|
||
self.state_.active_group.height = height_input.get_value() * 12;
|
||
self.update_floor_plan_();
|
||
} else {
|
||
height_input.set_value(self.state_.active_group.height);
|
||
}
|
||
});
|
||
|
||
// Sensor
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
};
|
||
|
||
/**
|
||
* Decorate the info pane for a room.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_info_pane_room_ = function(parent) {
|
||
const self = this;
|
||
|
||
const grid = $.createElement('div')
|
||
.style({
|
||
'display': 'grid',
|
||
'grid-template-columns': 'repeat(auto-fit, minmax(150px, 1fr))',
|
||
'column-gap': beestat.style.size.gutter
|
||
});
|
||
parent.appendChild(grid);
|
||
|
||
let div;
|
||
|
||
// Room Name
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const name_input = new beestat.component.input.text()
|
||
.set_label('Room Name')
|
||
.set_placeholder('Unnamed Room')
|
||
.set_width('100%')
|
||
.set_maxlength('50')
|
||
.set_requirements({
|
||
'required': true
|
||
})
|
||
.render(div);
|
||
|
||
if (this.state_.active_room_entity.get_room().name !== undefined) {
|
||
name_input.set_value(this.state_.active_room_entity.get_room().name);
|
||
}
|
||
|
||
name_input.addEventListener('input', function() {
|
||
self.state_.active_room_entity.get_room().name = name_input.get_value();
|
||
self.floor_plan_.update_infobox();
|
||
});
|
||
name_input.addEventListener('change', function() {
|
||
self.state_.active_room_entity.get_room().name = name_input.get_value();
|
||
self.update_floor_plan_();
|
||
});
|
||
|
||
// Elevation
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const elevation_input = new beestat.component.input.text()
|
||
.set_label('Elevation (feet)')
|
||
.set_placeholder(this.state_.active_group.elevation / 12)
|
||
.set_value(this.state_.active_room_entity.get_room().elevation / 12 || '')
|
||
.set_width('100%')
|
||
.set_maxlength('5')
|
||
.set_requirements({
|
||
'type': 'integer'
|
||
})
|
||
.render(div);
|
||
|
||
elevation_input.addEventListener('change', function() {
|
||
if (elevation_input.meets_requirements() === true) {
|
||
self.state_.active_room_entity.get_room().elevation = elevation_input.get_value() * 12;
|
||
self.update_floor_plan_();
|
||
self.rerender();
|
||
} else {
|
||
elevation_input.set_value('');
|
||
}
|
||
});
|
||
|
||
// Ceiling Height
|
||
div = $.createElement('div');
|
||
grid.appendChild(div);
|
||
const height_input = new beestat.component.input.text()
|
||
.set_label('Ceiling Height (feet)')
|
||
.set_placeholder(this.state_.active_group.height / 12)
|
||
.set_value(this.state_.active_room_entity.get_room().height / 12 || '')
|
||
.set_width('100%')
|
||
.set_maxlength('4')
|
||
.set_requirements({
|
||
'type': 'integer',
|
||
'min_value': 1
|
||
})
|
||
.render(div);
|
||
|
||
height_input.addEventListener('change', function() {
|
||
if (height_input.meets_requirements() === true) {
|
||
self.state_.active_room_entity.get_room().height = height_input.get_value() * 12;
|
||
self.update_floor_plan_();
|
||
} else {
|
||
height_input.set_value('');
|
||
}
|
||
});
|
||
|
||
// Sensor
|
||
div = $.createElement('div');
|
||
div.style('position', 'relative');
|
||
grid.appendChild(div);
|
||
const sensor_input = new beestat.component.input.select()
|
||
.add_option({
|
||
'label': 'None',
|
||
'value': ''
|
||
})
|
||
.set_width('100%')
|
||
.set_label('Sensor');
|
||
|
||
const sensors = {};
|
||
Object.values(beestat.cache.thermostat).forEach(function(thermostat) {
|
||
const thermostat_sensors = Object.values(beestat.cache.sensor).filter(function(sensor) {
|
||
return sensor.thermostat_id === self.thermostat_id_;
|
||
})
|
||
.sort(function(a, b) {
|
||
return a.name.localeCompare(b.name, 'en', {'sensitivity': 'base'});
|
||
});
|
||
|
||
sensors[thermostat.thermostat_id] = thermostat_sensors;
|
||
});
|
||
|
||
// Put the sensors in the select.
|
||
for (let thermostat_id in sensors) {
|
||
const thermostat = beestat.cache.thermostat[thermostat_id];
|
||
sensors[thermostat_id].forEach(function(sensor) {
|
||
sensor_input.add_option({
|
||
'group': thermostat.name,
|
||
'value': sensor.sensor_id,
|
||
'label': sensor.name
|
||
});
|
||
});
|
||
}
|
||
|
||
sensor_input.render(div);
|
||
|
||
if (self.state_.active_room_entity.get_room().sensor_id !== undefined) {
|
||
sensor_input.set_value(self.state_.active_room_entity.get_room().sensor_id);
|
||
} else {
|
||
sensor_input.set_value('');
|
||
}
|
||
|
||
sensor_input.addEventListener('change', function() {
|
||
const old_sensor_ids = Object.keys(beestat.floor_plan.get_sensor_ids_map(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
));
|
||
|
||
if (sensor_input.get_value() === '') {
|
||
delete self.state_.active_room_entity.get_room().sensor_id;
|
||
} else {
|
||
self.state_.active_room_entity.get_room().sensor_id = Number(sensor_input.get_value());
|
||
}
|
||
|
||
const new_sensor_ids = Object.keys(beestat.floor_plan.get_sensor_ids_map(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
));
|
||
|
||
// Delete data if the overall sensor set changes so it's re-fetched.
|
||
if (old_sensor_ids.sort().join(' ') !== new_sensor_ids.sort().join(' ')) {
|
||
beestat.cache.delete('data.three_d__runtime_sensor');
|
||
}
|
||
|
||
// For the help box
|
||
self.update_info_pane_();
|
||
|
||
self.update_floor_plan_();
|
||
});
|
||
|
||
// Help container
|
||
if (
|
||
Object.keys(beestat.floor_plan.get_sensor_ids_map(beestat.setting('visualize.floor_plan_id'))).length === 0 &&
|
||
this.state_.active_room_entity !== undefined
|
||
) {
|
||
const help_container = document.createElement('div');
|
||
Object.assign(help_container.style, {
|
||
'position': 'absolute',
|
||
'left': 0,
|
||
'top': '-9px'
|
||
});
|
||
div.appendChild(help_container);
|
||
|
||
this.helper_tile_ = new beestat.component.tile()
|
||
.set_text('Assign a sensor')
|
||
.set_shadow(false)
|
||
.set_background_color(beestat.style.color.green.base)
|
||
.set_text_color('#fff')
|
||
.set_type('pill')
|
||
.set_size('small')
|
||
.set_icon('arrow_down')
|
||
.render($(help_container));
|
||
|
||
sensor_input.set_label('⠀');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Rerender just the info pane to avoid rerendering the entire SVG for
|
||
* resizes, drags, etc. This isn't super ideal but without making the info
|
||
* pane a separate component this is the way.
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.update_info_pane_ = function() {
|
||
var old_parent = this.info_pane_container_;
|
||
this.info_pane_container_ = $.createElement('div')
|
||
.style('margin-top', beestat.style.size.gutter / 2);
|
||
|
||
this.decorate_info_pane_(this.info_pane_container_);
|
||
old_parent.parentNode().replaceChild(this.info_pane_container_, old_parent);
|
||
};
|
||
|
||
/**
|
||
* Rerender just the top floor pane tile to avoid rerendering the entire SVG
|
||
* for resizes, drags, etc. This isn't super ideal but without making the info
|
||
* pane a separate component this is the way.
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.update_floor_plan_tile_ = function() {
|
||
this.floor_plan_tile_.rerender();
|
||
};
|
||
|
||
/**
|
||
* Get the title of the card.
|
||
*
|
||
* @return {string} The title.
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.get_title_ = function() {
|
||
return 'Floor Plan';
|
||
};
|
||
|
||
/**
|
||
* Update the floor plan in the database. This is throttled so the update can
|
||
* only run so fast.
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.update_floor_plan_ = function() {
|
||
const self = this;
|
||
|
||
// Fake this event since the cache is being directly modified.
|
||
beestat.dispatcher.dispatchEvent('cache.floor_plan');
|
||
|
||
window.clearTimeout(this.update_timeout_);
|
||
this.update_timeout_ = window.setTimeout(function() {
|
||
new beestat.api()
|
||
.add_call(
|
||
'floor_plan',
|
||
'update',
|
||
{
|
||
'attributes': {
|
||
'floor_plan_id': beestat.setting('visualize.floor_plan_id'),
|
||
'data': self.get_floor_plan_data_(beestat.setting('visualize.floor_plan_id'))
|
||
}
|
||
},
|
||
'update_floor_plan'
|
||
)
|
||
.send();
|
||
}, 1000);
|
||
};
|
||
|
||
/**
|
||
* Get cloned floor plan data.
|
||
*
|
||
* @param {number} floor_plan_id Floor plan ID
|
||
*
|
||
* @return {object} The modified floor plan data.
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.get_floor_plan_data_ = function(floor_plan_id) {
|
||
return beestat.clone(beestat.cache.floor_plan[floor_plan_id].data);
|
||
};
|
||
|
||
/**
|
||
* Decorate the menu.
|
||
*
|
||
* @param {rocket.Elements} parent
|
||
*/
|
||
beestat.component.card.floor_plan_editor.prototype.decorate_top_right_ = function(parent) {
|
||
const self = this;
|
||
|
||
const menu = (new beestat.component.menu()).render(parent);
|
||
|
||
if (window.is_demo === false) {
|
||
if (Object.keys(beestat.cache.floor_plan).length > 1) {
|
||
menu.add_menu_item(new beestat.component.menu_item()
|
||
.set_text('Switch')
|
||
.set_icon('home_switch')
|
||
.set_callback(function() {
|
||
(new beestat.component.modal.change_floor_plan()).render();
|
||
}));
|
||
}
|
||
|
||
menu.add_menu_item(new beestat.component.menu_item()
|
||
.set_text('Add New')
|
||
.set_icon('plus')
|
||
.set_callback(function() {
|
||
new beestat.component.modal.create_floor_plan(
|
||
self.thermostat_id_
|
||
).render();
|
||
}));
|
||
|
||
if (beestat.setting('visualize.floor_plan_id') !== null) {
|
||
menu.add_menu_item(new beestat.component.menu_item()
|
||
.set_text('Edit')
|
||
.set_icon('pencil')
|
||
.set_callback(function() {
|
||
new beestat.component.modal.update_floor_plan(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
).render();
|
||
}));
|
||
}
|
||
|
||
if (beestat.setting('visualize.floor_plan_id') !== null) {
|
||
menu.add_menu_item(new beestat.component.menu_item()
|
||
.set_text('Delete')
|
||
.set_icon('delete')
|
||
.set_callback(function() {
|
||
new beestat.component.modal.delete_floor_plan(
|
||
beestat.setting('visualize.floor_plan_id')
|
||
).render();
|
||
}));
|
||
}
|
||
}
|
||
|
||
menu.add_menu_item(new beestat.component.menu_item()
|
||
.set_text('Help')
|
||
.set_icon('help_circle')
|
||
.set_callback(function() {
|
||
window.open('https://doc.beestat.io/86f6e4c44fc84c3cb4e8fb7b16d3d160');
|
||
}));
|
||
};
|