Room remeber size + component permissions
This commit is contained in:
@@ -76,6 +76,14 @@ class Component extends Item {
|
||||
return this.getAppDataItem("defaultEditor") == true;
|
||||
}
|
||||
|
||||
setRoomLastSize(size) {
|
||||
this.setAppDataItem("lastRoomSize", size);
|
||||
}
|
||||
|
||||
getRoomLastSize() {
|
||||
return this.getAppDataItem("lastRoomSize");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
An associative component depends on being explicitly activated for a given item, compared to a dissaciative component,
|
||||
|
||||
@@ -225,89 +225,24 @@ class ComponentManager {
|
||||
|
||||
if(message.action === "stream-items") {
|
||||
this.handleStreamItemsMessage(component, message);
|
||||
}
|
||||
|
||||
else if(message.action === "stream-context-item") {
|
||||
} else if(message.action === "stream-context-item") {
|
||||
this.handleStreamContextItemMessage(component, message);
|
||||
}
|
||||
|
||||
else if(message.action === "set-component-data") {
|
||||
component.componentData = message.data.componentData;
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
}
|
||||
|
||||
else if(message.action === "delete-items") {
|
||||
var items = message.data.items;
|
||||
var noun = items.length == 1 ? "item" : "items";
|
||||
if(confirm(`Are you sure you want to delete ${items.length} ${noun}?`)) {
|
||||
for(var item of items) {
|
||||
var model = this.modelManager.findItem(item.uuid);
|
||||
this.modelManager.setItemToBeDeleted(model);
|
||||
}
|
||||
|
||||
this.syncManager.sync();
|
||||
}
|
||||
}
|
||||
|
||||
else if(message.action === "create-item") {
|
||||
var responseItem = message.data.item;
|
||||
this.removePrivatePropertiesFromResponseItems([responseItem]);
|
||||
var item = this.modelManager.createItem(responseItem);
|
||||
if(responseItem.clientData) {
|
||||
item.setDomainDataItem(component.url, responseItem.clientData, ClientDataDomain);
|
||||
}
|
||||
this.modelManager.addItem(item);
|
||||
this.modelManager.resolveReferencesForItem(item);
|
||||
item.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
this.replyToMessage(component, message, {item: this.jsonForItem(item, component)})
|
||||
}
|
||||
|
||||
else if(message.action === "save-items") {
|
||||
var responseItems = message.data.items;
|
||||
|
||||
this.removePrivatePropertiesFromResponseItems(responseItems);
|
||||
|
||||
/*
|
||||
We map the items here because modelManager is what updates the UI. If you were to instead get the items directly,
|
||||
this would update them server side via sync, but would never make its way back to the UI.
|
||||
*/
|
||||
var localItems = this.modelManager.mapResponseItemsToLocalModels(responseItems, ModelManager.MappingSourceComponentRetrieved);
|
||||
|
||||
for(var item of localItems) {
|
||||
var responseItem = _.find(responseItems, {uuid: item.uuid});
|
||||
_.merge(item.content, responseItem.content);
|
||||
if(responseItem.clientData) {
|
||||
item.setDomainDataItem(component.url, responseItem.clientData, ClientDataDomain);
|
||||
}
|
||||
item.setDirty(true);
|
||||
}
|
||||
this.syncManager.sync((response) => {
|
||||
// Allow handlers to be notified when a save begins and ends, to update the UI
|
||||
var saveMessage = Object.assign({}, message);
|
||||
saveMessage.action = response && response.error ? "save-error" : "save-success";
|
||||
this.handleMessage(component, saveMessage);
|
||||
});
|
||||
}
|
||||
|
||||
else if(message.action === "install-local-component") {
|
||||
console.log("Received install-local-component event");
|
||||
this.desktopManager.installOfflineComponentFromData(message.data, (response) => {
|
||||
console.log("componentManager: installed component:", response);
|
||||
var component = this.modelManager.mapResponseItemsToLocalModels([response], ModelManager.MappingSourceComponentRetrieved)[0];
|
||||
// Save updated URL
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
})
|
||||
}
|
||||
|
||||
else if(message.action === "open-component") {
|
||||
} else if(message.action === "set-component-data") {
|
||||
this.handleSetComponentDataMessage(component, message);
|
||||
} else if(message.action === "delete-items") {
|
||||
this.handleDeleteItemsMessage(component, message);
|
||||
} else if(message.action === "create-item") {
|
||||
this.handleCreateItemMessage(component, message);
|
||||
} else if(message.action === "save-items") {
|
||||
this.handleSaveItemsMessage(component, message);
|
||||
} else if(message.action === "install-local-component") {
|
||||
this.handleInstallLocalComponentMessage(component, message);
|
||||
} else if(message.action === "open-component") {
|
||||
let openComponent = this.modelManager.findItem(message.data.uuid);
|
||||
console.log("Received open-component event", openComponent);
|
||||
this.openModalComponent(openComponent);
|
||||
}
|
||||
|
||||
// Notify observers
|
||||
for(let handler of this.handlers) {
|
||||
if(handler.areas.includes(component.area)) {
|
||||
this.timeout(function(){
|
||||
@@ -390,6 +325,124 @@ class ComponentManager {
|
||||
}.bind(this))
|
||||
}
|
||||
|
||||
handleSaveItemsMessage(component, message) {
|
||||
var requiredContentTypes = _.uniq(message.data.items.map((i) => {return i.content_type})).sort();
|
||||
var requiredPermissions = [
|
||||
{
|
||||
name: "stream-items",
|
||||
content_types: requiredContentTypes
|
||||
}
|
||||
];
|
||||
|
||||
this.runWithPermissions(component, requiredPermissions, message.permissions, () => {
|
||||
var responseItems = message.data.items;
|
||||
|
||||
this.removePrivatePropertiesFromResponseItems(responseItems);
|
||||
|
||||
/*
|
||||
We map the items here because modelManager is what updates the UI. If you were to instead get the items directly,
|
||||
this would update them server side via sync, but would never make its way back to the UI.
|
||||
*/
|
||||
var localItems = this.modelManager.mapResponseItemsToLocalModels(responseItems, ModelManager.MappingSourceComponentRetrieved);
|
||||
|
||||
for(var item of localItems) {
|
||||
var responseItem = _.find(responseItems, {uuid: item.uuid});
|
||||
_.merge(item.content, responseItem.content);
|
||||
if(responseItem.clientData) {
|
||||
item.setDomainDataItem(component.url, responseItem.clientData, ClientDataDomain);
|
||||
}
|
||||
item.setDirty(true);
|
||||
}
|
||||
this.syncManager.sync((response) => {
|
||||
// Allow handlers to be notified when a save begins and ends, to update the UI
|
||||
var saveMessage = Object.assign({}, message);
|
||||
saveMessage.action = response && response.error ? "save-error" : "save-success";
|
||||
this.handleMessage(component, saveMessage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
handleCreateItemMessage(component, message) {
|
||||
var requiredPermissions = [
|
||||
{
|
||||
name: "stream-items",
|
||||
content_types: [message.data.item.content_type]
|
||||
}
|
||||
];
|
||||
|
||||
this.runWithPermissions(component, requiredPermissions, message.permissions, () => {
|
||||
var responseItem = message.data.item;
|
||||
this.removePrivatePropertiesFromResponseItems([responseItem]);
|
||||
var item = this.modelManager.createItem(responseItem);
|
||||
if(responseItem.clientData) {
|
||||
item.setDomainDataItem(component.url, responseItem.clientData, ClientDataDomain);
|
||||
}
|
||||
this.modelManager.addItem(item);
|
||||
this.modelManager.resolveReferencesForItem(item);
|
||||
item.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
this.replyToMessage(component, message, {item: this.jsonForItem(item, component)})
|
||||
});
|
||||
}
|
||||
|
||||
handleDeleteItemsMessage(component, message) {
|
||||
var requiredContentTypes = _.uniq(message.data.items.map((i) => {return i.content_type})).sort();
|
||||
var requiredPermissions = [
|
||||
{
|
||||
name: "stream-items",
|
||||
content_types: requiredContentTypes
|
||||
}
|
||||
];
|
||||
|
||||
this.runWithPermissions(component, requiredPermissions, message.permissions, () => {
|
||||
var items = message.data.items;
|
||||
var noun = items.length == 1 ? "item" : "items";
|
||||
if(confirm(`Are you sure you want to delete ${items.length} ${noun}?`)) {
|
||||
for(var item of items) {
|
||||
var model = this.modelManager.findItem(item.uuid);
|
||||
this.modelManager.setItemToBeDeleted(model);
|
||||
}
|
||||
|
||||
this.syncManager.sync();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleInstallLocalComponentMessage(component, message) {
|
||||
var requiredPermissions = [
|
||||
{
|
||||
name: "stream-items",
|
||||
content_types: [message.data.content_type]
|
||||
}
|
||||
];
|
||||
|
||||
this.runWithPermissions(component, requiredPermissions, message.permissions, () => {
|
||||
console.log("Received install-local-component event");
|
||||
this.desktopManager.installOfflineComponentFromData(message.data, (response) => {
|
||||
console.log("componentManager: installed component:", response);
|
||||
var component = this.modelManager.mapResponseItemsToLocalModels([response], ModelManager.MappingSourceComponentRetrieved)[0];
|
||||
// Save updated URL
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
handleSetComponentDataMessage(component, message) {
|
||||
var requiredPermissions = [
|
||||
{
|
||||
name: "stream-items",
|
||||
content_types: component.content_type
|
||||
}
|
||||
];
|
||||
|
||||
this.runWithPermissions(component, requiredPermissions, message.permissions, () => {
|
||||
component.componentData = message.data.componentData;
|
||||
component.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
});
|
||||
}
|
||||
|
||||
runWithPermissions(component, requiredPermissions, requestedPermissions, runFunction) {
|
||||
|
||||
var acquiredPermissions = component.permissions;
|
||||
@@ -407,7 +460,7 @@ class ComponentManager {
|
||||
if(!requestedMatchesRequired) {
|
||||
// Error with Component permissions request
|
||||
console.error("You are requesting permissions", requestedPermissions, "when you need to be requesting", requiredPermissions, ". Component:", component);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!component.permissions) {
|
||||
|
||||
@@ -11,29 +11,36 @@ class RoomBar {
|
||||
'ngInject';
|
||||
|
||||
$scope.componentManager = componentManager;
|
||||
$scope.rooms = [];
|
||||
|
||||
$rootScope.$on("initial-data-loaded", () => {
|
||||
$timeout(() => {
|
||||
$scope.rooms = componentManager.componentsForArea("rooms");
|
||||
})
|
||||
modelManager.addItemSyncObserver("room-bar", "SN|Component", (allItems, validItems, deletedItems, source) => {
|
||||
$scope.rooms = _.uniq($scope.rooms
|
||||
.concat(allItems
|
||||
.filter((candidate) => {return candidate.area == "rooms"})))
|
||||
.filter((candidate) => {return !candidate.deleted});
|
||||
});
|
||||
|
||||
componentManager.registerHandler({identifier: "roomBar", areas: ["rooms"], activationHandler: function(component){
|
||||
componentManager.registerHandler({identifier: "roomBar", areas: ["rooms"], activationHandler: (component) => {
|
||||
if(component.active) {
|
||||
$timeout(function(){
|
||||
$timeout(() => {
|
||||
var iframe = componentManager.iframeForComponent(component);
|
||||
if(iframe) {
|
||||
var lastSize = component.getRoomLastSize();
|
||||
if(lastSize) {
|
||||
componentManager.handleSetSizeEvent(component, lastSize);
|
||||
}
|
||||
iframe.onload = function() {
|
||||
componentManager.registerComponentWindow(component, iframe.contentWindow);
|
||||
}.bind(this);
|
||||
}
|
||||
}.bind(this));
|
||||
});
|
||||
}
|
||||
}.bind(this), actionHandler: function(component, action, data){
|
||||
}, actionHandler: (component, action, data) => {
|
||||
if(action == "set-size") {
|
||||
componentManager.handleSetSizeEvent(component, data);
|
||||
component.setRoomLastSize(data);
|
||||
}
|
||||
}.bind(this)});
|
||||
}});
|
||||
|
||||
$scope.selectRoom = function(room) {
|
||||
room.show = !room.show;
|
||||
|
||||
@@ -16,6 +16,7 @@ class PackageManager {
|
||||
}
|
||||
|
||||
var assembled = this.modelManager.createItem(aPackage);
|
||||
assembled.package_info = aPackage;
|
||||
this.modelManager.addItem(assembled);
|
||||
assembled.setDirty(true);
|
||||
this.syncManager.sync();
|
||||
|
||||
@@ -95,6 +95,21 @@ h2 {
|
||||
.room-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-size: 11px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.room-container {
|
||||
max-height: 85vh;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.room-item{"ng-repeat" => "room in rooms", "ng-click" => "selectRoom(room)"}
|
||||
%span {{room.name}}
|
||||
%img.icon{"ng-src" => "{{room.package_info.icon_bar}}"}
|
||||
.label {{room.name}}
|
||||
.room-container.panel-right{"ng-if" => "room.show && room.active", "ng-attr-id" => "component-{{room.uuid}}"}
|
||||
%iframe.room-iframe{"ng-src" => "{{componentManager.urlForComponent(room) | trusted}}", "frameBorder" => "0", "sandbox" => "allow-scripts allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox allow-modals", "data-component-id" => "{{room.uuid}}"}
|
||||
|
||||
@@ -53,7 +53,7 @@ module Neeto
|
||||
font_src: %w(* 'self'),
|
||||
form_action: %w('self'),
|
||||
frame_ancestors: ["*"],
|
||||
img_src: %w('self' data:),
|
||||
img_src: %w('self' * data:),
|
||||
manifest_src: %w('self'),
|
||||
media_src: %w('self'),
|
||||
object_src: %w('self'),
|
||||
|
||||
Reference in New Issue
Block a user