Commit 91eb2c9d authored by damianofalcioni's avatar damianofalcioni

added layout library

parent c5930f4e
......@@ -6,18 +6,32 @@
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/codemirror.min.css" integrity="sha256-I8NyGs4wjbMuBSUE40o55W6k6P7tu/7G28/JGUUYCIs=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.11/summernote.css" integrity="sha256-vHGOIPxeMV4uIsqGDzob0M6Zl8PY5+nJh7m0hJhJXfg=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-base.css" integrity="sha256-oIDR18yKFZtfjCJfDsJYpTBv1S9QmxYopeqw2dO96xM=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" integrity="sha256-rByPlHULObEjJ6XQxW/flG2r+22R5dKiAoef+aXWfik=" crossorigin="anonymous" />
<!-- translucent soda light dark -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-light-theme.css"
crossorigin="anonymous"/>
<!--
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-translucent-theme.css" integrity="sha256-tm4Yzc/26f04ZInrqbiofqzCK6k3bkMftQcNEceTVug=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-soda-theme.css" integrity="sha256-kv/F2vL/CA9Au5qh6sbsjuCEKFCNjYe8I+RxOejuIFM=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-light-theme.css" integrity="sha256-K+deaiB23AJKqNRDy+M1oIAzXV41ykML5dKZmZhFgeg=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-dark-theme.css" integrity="sha256-ygw8PvSDJJUGLf6Q9KIQsYR3mOmiQNlDaxMLDOx9xL0=" crossorigin="anonymous" />
-->
</head>
<body>
<!--[if IE]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience and security.</p>
<![endif]-->
<br>
<div class="container">
<div class="container-fluid">
<div id="main"></div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-3.3.1.min.js"><\/script>')</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha256-KM512VNnjElC30ehFwehXjx1YCHPiQkOPmqnrWtpccM=" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/codemirror.min.js" integrity="sha256-OMbqhJ5GYA+UQ2a9UE9iXHA1kn3hlZCFL5aZmpSp/+M=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/mode/javascript/javascript.min.js" integrity="sha256-h2CaV12bheEEc7Ao3zF6MntAbDLJkPoFR+h+nHvQUqA=" crossorigin="anonymous"></script>
......@@ -27,6 +41,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/mode/markdown/markdown.min.js" integrity="sha256-BZXkUzlSBobUXEiSFbDIbTc/DOqhNdegF/iK5m99kbk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.11/summernote.min.js" integrity="sha256-1XDZ8T0bWi65wnqq7bBPK9QrWkE0fg6xLVAVuSqKw/4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js" integrity="sha256-LSUpTY0kkXGKvcBC9kbmgibmx3NVVgJvAEfTZbs51mU=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/goldenlayout.min.js" integrity="sha256-NhJAZDfGgv4PiB+GVlSrPdh3uc75XXYSM4su8hgTchI=" crossorigin="anonymous"></script>
<script src="js/OliveUI.js"></script>
<script src="js/modules/newWidgetUI.js"></script>
......@@ -34,6 +49,7 @@
<script src="js/modules/newHTMLEditorUI.js"></script>
<script src="js/modules/newMicroserviceUI.js"></script>
<script src="js/modules/newMicroserviceUI_configUI.js"></script>
<script src="js/modules/newLayout_GoldenLayout.js"></script>
<script src="js/widgets/MicroserviceUI_manifest.js"></script>
<script src="js/widgets/JavascriptRenderUI_manifest.js"></script>
......
......@@ -5,82 +5,168 @@
if (typeof $.fn.popover != 'function') throw 'Bootstrap Required';
var _statics = {
createWidgetInstance: function (widgetName, _dom, _state) {
var widgetManifest = OliveUI.widgetsManifests[widgetName];
if (!widgetManifest) throw 'Impossible to find the manifest of the widget ' + widgetName;
createWidgetInstance: function (_dom, _sub, _state, uuid, widgetName, addToLayout) {
var _widgetManifest = OliveUI.widgetsManifests[widgetName];
if (!_widgetManifest) throw 'Impossible to find the manifest of the widget ' + widgetName;
if (!OliveUI.modules.newWidgetUI) throw 'Missing newWidgetUI module';
var uuid = OliveUI.utils.generateUUID();
var widgetRootDiv = $('<div>');
var widget = OliveUI.modules.newWidgetUI({
var _widget = OliveUI.modules.newWidgetUI({
initialView: 'render',
headerVisible: false,
widgetTitle: widgetName,
removeBtnClickFn: function () {
widgetRootDiv.remove();
delete _state.widgetInstances[uuid];
_statics.deleteWidgetInstance(_state, uuid);
},
renderModule: widgetManifest.createUIFn(),
configModule: widgetManifest.createConfigurationUIFn ? widgetManifest.createConfigurationUIFn() : null,
mappingFn: widgetManifest.configurationMappingFn ? function (configOutput, renderInput) {
widgetManifest.configurationMappingFn(widget, configOutput, renderInput);
renderModule: _widgetManifest.createUIFn(),
configModule: _widgetManifest.createConfigurationUIFn ? _widgetManifest.createConfigurationUIFn() : null,
mappingFn: _widgetManifest.configurationMappingFn ? function (configOutput, renderInput) {
_widgetManifest.configurationMappingFn({
setWidgetTitle: function (title) {
_widget.setWidgetTitle(title);
_sub.layoutManager.setTitle(uuid, title);
}
}, configOutput, renderInput);
} : null
});
_dom.rootDiv.append(
widgetRootDiv.append(
widget.render()
)
);
_state.widgetInstances[uuid] = {
widgetName: widgetName,
widget: widget,
widgetRootDiv: widgetRootDiv
manifest: _widgetManifest,
widget: _widget,
rootDiv: $('<div>').append(
_widget.render()
)
};
_state.instancesIdList.push(uuid);
if (addToLayout) {
_sub.layoutManager.addDomElLayoutConfiguration(uuid);
}
_sub.layoutManager.addDomEl(uuid, _state.widgetInstances[uuid].rootDiv);
_sub.layoutManager.setTitle(uuid, widgetName);
},
deleteWidgetInstance: function (_state, uuid) {
if (!_state.widgetInstances[uuid]) return;
_state.widgetInstances[uuid].rootDiv.remove();
delete _state.widgetInstances[uuid];
_state.instancesIdList.splice(_state.instancesIdList.indexOf(uuid), 1);
},
return uuid;
getWidgetInstanceConfiguration: function (_state, widgetUUID) {
var _widgetInstance = _state.widgetInstances[widgetUUID];
if (!_widgetInstance) throw 'Impossible to find the widget instance ' + widgetUUID;
return _widgetInstance.widget.getContent();
},
getWidgetInstanceConfiguration: function (widgetUUID, _state) {
var widgetState = _state.widgetInstances[widgetUUID];
if (!widgetState) throw 'Impossible to find the widget instance ' + widgetUUID;
return widgetState.widget.getContent();
setWidgetInstanceConfiguration: function (_state, widgetUUID, widgetContent) {
var _widgetInstance = _state.widgetInstances[widgetUUID];
if (!_widgetInstance) throw 'Impossible to find the widget instance ' + widgetUUID;
_widgetInstance.widget.setContent(widgetContent);
},
setWidgetInstanceConfiguration: function (widgetUUID, widgetContent, _state) {
var widgetState = _state.widgetInstances[widgetUUID];
if (!widgetState) throw 'Impossible to find the widget instance ' + widgetUUID;
widgetState.widget.setContent(widgetContent);
getContent: function (_sub, _state) {
var widgetInstancesRet = {};
$.each(_state.widgetInstances, function (uuid, widgetInstance) {
widgetInstancesRet[uuid] = {
manifestName: widgetInstance.manifest.name,
widgetContent: widgetInstance.widget.getContent()
};
});
return {
widgetInstances: widgetInstancesRet,
widgetInstanceIdList: _state.instancesIdList,
layout: {
name: 'golden-layout',
content: _sub.layoutManager.getContent()
}
};
},
setContent: function (_dom, _sub, _state, content) {
content.widgetInstanceIdList = content.widgetInstanceIdList || [];
content.widgetInstances = content.widgetInstances || {};
content.layout = content.layout || {};
content.layout.name = content.layout.name || 'golden-layout';
content.layout.content = content.layout.content || {};
_state.instancesIdList = [];
_state.widgetInstances = {};
$.each(content.widgetInstanceIdList, function (i, uuid) {
var widgetInstanceContent = content.widgetInstances[uuid];
widgetInstanceContent.widgetContent = widgetInstanceContent.widgetContent || {};
if (!widgetInstanceContent.manifestName) throw 'Impossible to find the manifestName for the widget instance ' + uuid;
_statics.createWidgetInstance(_dom, _sub, _state, uuid, widgetInstanceContent.manifestName, false);
_state.widgetInstances[uuid].widget.setContent(widgetInstanceContent.widgetContent);
_sub.layoutManager.addDomEl(uuid, _state.widgetInstances[uuid].rootDiv);
});
_sub.layoutManager.setContent(content.layout.content);
}
};
var OliveUI = function (config = {}) {
if (!OliveUI.modules.newLayout_GoldenLayout) throw 'Missing newLayout_GoldenLayout module';
var _state = {
widgetInstances: {}
var _sub = {
layoutManager: OliveUI.modules.newLayout_GoldenLayout({
initialLayout: 'stack', //column stack row
onWidgetCloseFn: function (uuid) {
_statics.deleteWidgetInstance(_state, uuid);
},
onWidgetConfigFn: function (uuid) {
var _widgetInstance = _state.widgetInstances[uuid];
if (!_widgetInstance) throw 'Impossible to find the widget instance ' + uuid;
_widgetInstance.widget.showConfigView();
},
onWidgetRefreshFn: function (uuid) {
var _widgetInstance = _state.widgetInstances[uuid];
if (!_widgetInstance) throw 'Impossible to find the widget instance ' + uuid;
_widgetInstance.widget.showRenderView();
}
})
};
var _dom = {
rootDiv: $('<div>')
rootDiv: $('<div>').append(
_sub.layoutManager.render()
)
};
var _state = {
widgetInstances: {},
instancesIdList: []
};
return {
render: function () {
return _dom.rootDiv;
},
createWidgetInstance: function (widgetName) {
return _statics.createWidgetInstance(widgetName, _dom, _state);
createWidgetInstance: function (widgetName, uuid) {
uuid = uuid || OliveUI.utils.generateUUID();
_statics.createWidgetInstance(_dom, _sub, _state, uuid, widgetName, true);
return uuid;
},
getWidgetInstanceConfiguration: function (widgetUUID) {
return _statics.getWidgetInstanceConfiguration(widgetUUID, _state);
return _statics.getWidgetInstanceConfiguration(_state, widgetUUID);
},
setWidgetInstanceConfiguration: function (widgetUUID, widgetContent) {
_statics.setWidgetInstanceConfiguration(widgetUUID, widgetContent, _state);
_statics.setWidgetInstanceConfiguration(_state, widgetUUID, widgetContent);
},
getContent: function () {
return _statics.getContent(_sub, _state);
},
setContent: function (content = {}) {
_statics.setContent(_dom, _sub, _state, content);
}
};
};
......@@ -247,6 +333,16 @@
reader.readAsDataURL(file);
},
ab2str: function (ab) {
if (!(window.TextDecoder)) throw 'This browser does not support TextDecoder';
return new TextDecoder("utf-8").decode(ab);
},
str2ab: function (str) {
if (!(window.TextEncoder)) throw 'This browser does not support TextEncoder';
return new TextEncoder().encode(str);
},
arr2obj: function (arr, idName) {
var ret = {};
arr.forEach(function (arrObj) {
......@@ -281,7 +377,28 @@
});
});
return ret;
},
download: function (data, filename, type) {
var file = new Blob([data], {
type: type
});
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
};
return _utils;
}());
......
......@@ -49,4 +49,25 @@ return $('<button>This is a javascript generated button</button>').click(functio
text: `# This is a markdown text`
});
var toSave = oliveUI.getContent();
console.log(toSave);
oliveUI.setContent(toSave);
$('#main').prepend(
$('<button>Download</button>').click(function () {
OliveUI.utils.download(JSON.stringify(oliveUI.getContent()), 'oliveui_backup_' + new Date().toISOString() + '.json', 'application/json');
}),
$('<button>Upload</button>').click(function () {
$('#fileUpload').trigger('click');
}),
$('<input id="fileUpload" type="file" style="display: none;">').change(function (e) {
var fileName = e.target.files[0].name;
OliveUI.utils.readFileAsArrayBuffer(e.target.files[0], function (content) {
oliveUI.setContent(JSON.parse(OliveUI.utils.ab2str(content)));
});
})
);
}(jQuery, OliveUI));
(function ($, OliveUI, GoldenLayout) {
if (typeof $('<div>').resizable != 'function') throw 'JQuery UI Required';
var _statics = {
init: function (_dom, _state, config, content) {
if (_state.layoutManager != null) throw 'Layout Manager already initialized';
_state.layoutManager = new GoldenLayout({
content: content,
settings: {
hasHeaders: config.showHeaders,
showPopoutIcon: false
}
}, _dom.rootDiv);
_state.layoutManager.init();
$(window).on('resize', function () {
_state.layoutManager.updateSize();
});
_dom.rootDiv.on('resize', function () {
_state.layoutManager.updateSize();
});
_state.layoutManager.on('initialised', function () {
_state.layoutManager.root.addChild(_state.initialLayoutContent);
});
_state.layoutManager.on('stackCreated', function (stack) {
stack.header.controlsContainer.find('.lm_close').off('click').click(function () {
var activeContentItem = stack.getActiveContentItem();
var uuid = activeContentItem.config.componentState.uuid;
config.onWidgetCloseFn(uuid);
activeContentItem.remove();
});
stack.header.controlsContainer.prepend($('<li class="glyphicon glyphicon-wrench"></li>').click(function () {
var uuid = stack.getActiveContentItem().container.getState().uuid;
config.onWidgetConfigFn(uuid);
}));
stack.header.controlsContainer.prepend($('<li class="glyphicon glyphicon-refresh"></li>').click(function () {
var uuid = stack.getActiveContentItem().container.getState().uuid;
config.onWidgetRefreshFn(uuid);
}));
});
_state.layoutManager.on('tabCreated', function (tab) {
tab.closeElement.off('click').click(function () {
var activeContentItem = tab.contentItem;
var uuid = activeContentItem.config.componentState.uuid;
config.onWidgetCloseFn(uuid);
activeContentItem.remove();
});
});
_state.layoutManager.registerComponent('default', function (container, state) {
var domEl = _state.availableDomEls[state.uuid];
if (!domEl) throw 'Incorrectly initialized Dom for ' + state.uuid;
if (domEl)
container.getElement().html(domEl);
});
},
addDomEl: function (_state, uuid, domEl) {
_state.availableDomEls[uuid] = domEl;
},
addDomElLayoutConfiguration: function (_state, config, uuid) {
var _domLayoutConf = {
type: 'component',
componentName: 'default',
title: uuid,
id: uuid,
isClosable: config.allowClose,
componentState: {
uuid: uuid
}
};
if (_state.layoutManager.root) {
_state.layoutManager.root.contentItems[0].addChild(_domLayoutConf);
} else {
_state.initialLayoutContent.content.push(_domLayoutConf);
}
},
setTitle: function (_state, uuid, title) {
if (_state.layoutManager.root) {
if (_state.layoutManager.root.getItemsById(uuid).length != 0)
_state.layoutManager.root.getItemsById(uuid)[0].setTitle(title);
} else {
var _getItemsByIdFn = function (currentContent) {
if (currentContent.id == uuid)
return currentContent;
if (currentContent.content)
for (var i = 0; i < currentContent.content.length; i++) {
var ret = _getItemsByIdFn(currentContent.content[i]);
if(ret)
return ret;
}
return null;
};
var item = _getItemsByIdFn(_state.initialLayoutContent);
if(item)
item.title = title;
}
},
setContent: function (_dom, _state, config, content) {
content.content = content.content || [];
content.rootWidth = content.rootWidth || '100%';
content.rootHeight = content.rootHeight || '100vh';
//_state.layoutManager.updateSize(content.rootWidth, content.rootHeight);
_dom.rootDiv.css({
width: content.rootWidth,
height: content.rootHeight
});
if (_state.layoutManager.root) {
//https://github.com/golden-layout/golden-layout/issues/350
_state.layoutManager.root.contentItems.forEach(function (item) {
item.remove();
});
content.content.forEach(function (item) {
_state.layoutManager.root.addChild(item);
});
} else {
if (content.content.length == 1)
_state.initialLayoutContent = content.content[0];
else
_state.initialLayoutContent.content = content.content;
}
},
getContent: function (_dom, _state) {
return {
content: _state.layoutManager.isInitialised ? _state.layoutManager.toConfig().content : [_state.initialLayoutContent],
width: _dom.rootDiv.width(),
height: _dom.rootDiv.height()
};
}
};
var _newLayout_GoldenLayout = function (config = {}) {
config.initialLayout = config.initialLayout || 'stack';
config.onWidgetCloseFn = config.onWidgetCloseFn || function (uuid) {};
config.onWidgetConfigFn = config.onWidgetConfigFn || function (uuid) {};
config.onWidgetRefreshFn = config.onWidgetRefreshFn || function (uuid) {};
config.allowClose = config.allowClose != null ? config.allowClose : true;
config.allowResize = config.allowResize != null ? config.allowResize : true;
config.showHeaders = config.showHeaders != null ? config.showHeaders : true;
var _state = {
layoutManager: null,
availableDomEls: {},
initialLayoutContent: {
type: config.initialLayout,
content: []
}
};
var _dom = {
rootDiv: $('<div>').css("height", "90vh").resizable({
disabled: !config.allowResize
}).append('<style>.lm_content > div > .panel { height: 100%; width: 100%; position: absolute; overflow: auto;} < /style>')
};
_statics.init(_dom, _state, config, []);
return {
render: function () {
return _dom.rootDiv;
},
setContent: function (content = {}) {
_statics.setContent(_dom, _state, config, content);
},
getContent: function () {
return _statics.getContent(_dom, _state);
},
addDomEl: function (uuid, domEl) {
_statics.addDomEl(_state, uuid, domEl);
},
addDomElLayoutConfiguration: function (uuid, domLayoutConf = {}) {
_statics.addDomElLayoutConfiguration(_state, config, uuid);
},
setTitle: function (uuid, title) {
_statics.setTitle(_state, uuid, title);
}
};
};
OliveUI.modules.newLayout_GoldenLayout = _newLayout_GoldenLayout;
}($, OliveUI, GoldenLayout));
......@@ -3,9 +3,9 @@
var _statics = {
ui: {
render: function (_dom) {
render: function (_dom, config) {
if (!Utils.isStyled('panel-title')) throw 'Bootstrap css Required';
if (config.headerVisible) {
return _dom.panelRoot.append(
`<style>
.link{
......@@ -33,10 +33,21 @@
_dom.rootDiv.append(
_dom.renderModuleDom,
_dom.configModuleDom))));
} else {
return _dom.panelRoot.append(
$('<div class="panel-body">').append(
_dom.messageDiv,
_dom.rootDiv.append(
_dom.renderModuleDom,
_dom.configModuleDom))
);
}
},
setContent: function (_dom, _state, config, content) {
_state.content = content;
_state.contentInitialized = true;
if (config.configModule)
config.configModule.setContent(_state.content);
_statics.widget.refreshCurrentView(_dom, config, _state);
},
getContent: function (_state, config) {
......@@ -104,6 +115,7 @@
config.refreshBtnVisible = config.refreshBtnVisible != null ? config.refreshBtnVisible : true;
config.settingBtnVisible = config.settingBtnVisible != null ? config.settingBtnVisible : true;
config.deleteBtnVisible = config.deleteBtnVisible != null ? config.deleteBtnVisible : true;
config.headerVisible = config.headerVisible != null ? config.headerVisible : true;
config.mappingFn = config.mappingFn || function (configOutput, renderInput) {
Object.assign(renderInput, configOutput);
};
......@@ -157,7 +169,7 @@
return {
render: function () {
return _statics.ui.render(_dom);
return _statics.ui.render(_dom, config);
},
setContent: function (content = {}) {
_statics.ui.setContent(_dom, _state, config, content);
......@@ -173,6 +185,12 @@
},
getConfig: function () {
return config;
},
showConfigView: function () {
_statics.widget.showConfigView(_dom, config, _state);
},
showRenderView: function () {
_statics.widget.showRenderView(_dom, config, _state);
}
};
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment