/*global UB, js_beautify, mxEvent, mxUtils, mxEditor, mxRubberband, mxCodec, mxBasePath, mxVertexHandler, mxCellRenderer, mxCell, mxGeometry, mxPoint, console, isDeveloperMode, mxRubberband */
//Ext.Loader.loadScript({
// url: mxBasePath + "/js/graphEditor/Shapes.js"
//});
/*
if (!UB.isJSLINTLoaded) {
Ext.Loader.loadScript('models/UBS/js_beautify.js');
Ext.Loader.loadScript('models/UBS/jslint.js');
UB.isJSLINTLoaded = true;
}
*/
/**
* Metadata ER diagram editor.
*/
Ext.define('UB.ux.UBMetaDiagram', {
extend: 'Ext.Panel',
alias: 'widget.UBMetaDiagram',
width: '100%',
height: '100%',
layout: 'fit',
//cls: 'mx-graph-editor',
statics: {
mixinPictures: {
mStorage: '<i class="fa fa-database"></i>',
dataHistory: '<i class="fa fa-clock-o"></i>',
unity: '<i class="fa fa-toggle-off"></i>',
tree: '<i class="fa fa-sitemap"></i>',
fts: '<i class="fa fa-search"></i>',
rls: '<i class="fa fa-tasks"></i>',
als: '<i class="fa fa-table"></i>',
aclRls: '<i class="fa fa-tasks">a</i>',
audit: '<i class="fa fa-pencil-square-o"></i>',
softLock: '<i class="fa fa-key"></i>',
clobTruncate: 'ct'
}
},
initComponent: function(){
var me = this, id, html, toolbarHtml, outlineHtml;
UB.inject("models/UBS/js_beautify.js").done();
//UB.inject("models/UBS/jslint.js").done();
me.addEvents('change');
me.items = me.items || [];
me.initObjectTree();
Ext.EventManager.on(document, 'mouseup', me.onmouseUpFunc ,me);
Ext.EventManager.on(document, 'mousemove', me.onmousemoveFunc ,me);
me.idPrefix = Ext.id(null);
me.containerId = id = me.idPrefix + 'graph';
html = '<div id="' + id+'" class="graph-editor-holder" style="width: 100%; height: 100%;-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;" tabindex="0"></div>';
me.editPnl = Ext.create('Ext.panel.Panel',{
//layout: 'fit',
region:'center',
cls: 'mx-graph-editor',
flex: 1,
html: html,
listeners: {
boxready: function(/*sender*/){
if (isDeveloperMode){
me.initMXEditor();
} else {
UB.inject('jslibs/mxGraph/javascript/src/js/mxClient.js')
.then(function(){
return UB.inject(mxBasePath + '/js/graphEditor/Shapes.js');
}).done(function(){
me.initMXEditor();
});
}
},
resize: function(){
if (this.editor && this.editor.graph){
this.editor.graph.sizeDidChange();
}
},
scope: me
}
});
me.toolbarId = id = me.idPrefix + 'toolbar';
toolbarHtml = '<div id="' + id+'" tabindex="0"></div>';
me.outlineId = id = me.idPrefix + 'outline';
outlineHtml = '<div id="' + id+'" ></div>';
me.menuPnl = Ext.create('Ext.panel.Panel',{
height: '100%',
region:'west',
split: true,
collapsible: true,
width: 250,
layout: {
type: 'border'
},
items: [
{
xtype: 'tabpanel',
region:'center',
deferredRender: false,
split: true,
height: 'auto',
bodyStyle: 'background:white;',
items : [
me.objectTree,
{
xtype: 'panel',
region:'center',
autoRender: true,
title: UB.i18n('toolbar'),
html: toolbarHtml,
listeners: {
boxready: function(sender){
//Ext.get(me.toolbarId).dom.appendChild(me.editor.toolbar.toolbar.container);
},
scope: me
}
}
]
},
{
xtype: 'panel',
region:'south',
split: true,
height: 160,
fit: 2,
//layout: 'fit',
html: outlineHtml
}
]
});
var innerPnl = Ext.create('Ext.panel.Panel',{
layout: {
type: 'border'
},
defaults: {
split: true
},
items: [
me.menuPnl,
me.editPnl
]
// ,listeners: {
// boxready: function(sender){
// this.initMainPanel(sender);
// },
// scope: me
// }
});
me.items.push(innerPnl);
me.callParent(arguments);
},
isDirty: function(){
return (this.editor ? this.editor.isModified(): false);
},
// initMainPanel: function(sender){
// /*
// var me = this, basepanel, saveAction;
// basepanel = me.up('basepanel');
// me.docContainer = basepanel.getUBCmp('attrDocument');
//
//
// saveAction = basepanel.actions[UB.view.BasePanel.actionId.save];
// me.baseSaveActionHandler = Ext.bind(saveAction.initialConfig.handler, basepanel);
// saveAction.setHandler(me.onBaseFormSave, me);
// */
// },
onmousemoveFunc: function(evnt){
var me = this;
if (!me.dragDropObj || !me.dragDropObj.dragElm){
return;
}
var currXY= evnt.getXY();
//basewindow.dom.style.zIndex + 2,
Ext.get(me.dragDropObj.dragElm).position("absolute", me.dragDropObj.dragElm.style.zIndex, currXY[0] , currXY[1] );
},
onmouseUpFunc: function(e){
var me = this, x, y, pt;
if (!me.dragDropObj){
return;
}
if (!me.graphDivEl){
return;
}
if (me.dragDropObj.dragElm){
me.dragDropObj.dragElm.parentNode.removeChild(me.dragDropObj.dragElm);
}
x = e.getX();
y = e.getY();
if (me.graphDivEl.getX() > x ||
me.graphDivEl.getX() + me.graphDivEl.getWidth() < x ||
me.graphDivEl.getY() > y ||
me.graphDivEl.getY() + me.graphDivEl.getHeight() < y ){
me.dragDropObj = null;
return;
}
x = mxEvent.getClientX(e.browserEvent);
y = mxEvent.getClientY(e.browserEvent);
pt = mxUtils.convertPoint( me.editor.graph.container, x, y);
me.addObjectToDiagram(pt, me.dragDropObj);
me.dragDropObj = null;
},
addObjectToDiagram: function(pt, config){
var me = this, vertex, doc, node, metaObj, objLinks = {}, linkmetaObj, lnkType,
objCode = config.objectName, objExists = false, lnk;
// find exist UB obj
Ext.Object.each(me.editor.graph.model.cells, function(id,cell){
var objectCode = cell.getAttribute('objectCode');
if (!objectCode){
return true;
}
if (objCode.toUpperCase() === objectCode.toUpperCase()){
objExists = true;
return false;
}
},me);
if (objExists){
$App.dialogError('Object exist in diagram').done();
return false;
}
doc = mxUtils.createXmlDocument();
node = doc.createElement('ubObject');
node.setAttribute('label', objCode );
node.setAttribute('objectCode', objCode);
//;verticalAlign=top;align=left;spacingLeft=36; overflow=fill; shape=component; spacingTop=2;spacingLeft=2;spacingRight=2;spacingBottom=2;
vertex = new mxCell(node, new mxGeometry(0, 0, 187, 147), 'verticalAlign=top;align=left;overflow=fill;html=1');
vertex.vertex = true;
//vertex.setId(me.dragDropObj.objectName);
metaObj = $App.domainInfo.get(objCode);
me.editor.addVertex( null, vertex, pt.x, pt.y); // me.editor.graph.getDefaultParent()
metaObj.eachAttribute(function(attr, attrCode){
if (Ext.String.startsWith(attrCode, 'mi_', true )){
return true;
}
if (attr.dataType === 'Entity' && attrCode.toUpperCase() !== 'ID' ){
lnk = objLinks[attr.associatedEntity];
if (!lnk){
objLinks[attr.associatedEntity] = lnk = [];
}
lnk.push({ linkType: 'relation', srcObj: objCode,
srcProp: attrCode , destObj: attr.associatedEntity, destProp: 'ID' });
}
}, me);
if (metaObj.mixins && metaObj.mixins.unity /*&& metaObj.mixins.unity.enabled */){
lnk = objLinks[metaObj.mixins.unity.entity];
if (!lnk){
objLinks[metaObj.mixins.unity.entity] = lnk = [];
}
lnk.push({ linkType: 'inheritage', srcObj: objCode,
srcProp: 'ID' , destObj: metaObj.mixins.unity.entity, destProp: 'ID' });
}
Ext.Object.each(me.editor.graph.model.cells, function(id,cell){
var objectCode = cell.getAttribute('objectCode');
if (!objectCode){
return true;
}
linkmetaObj = $App.domainInfo.get(objectCode);
if (!linkmetaObj){
return true;
}
// other objects inherited from me
if (linkmetaObj.mixins && linkmetaObj.mixins.unity && /* linkmetaObj.mixins.unity.enabled && */
linkmetaObj.mixins.unity.entity === objCode){
lnkType = { linkType: 'inheritage', srcObj: objectCode,
srcProp: 'ID' , destObj: objCode, destProp: 'ID' };
me.editor.graph.addEdge(me.createEdge(lnkType), null, cell, vertex );
}
// obj link to other
if (objLinks[objectCode]){
Ext.Array.each(objLinks[objectCode], function(val){
me.editor.graph.addEdge(me.createEdge(val), null, vertex, cell );
}, me );
}
// other objs link to me (if is not inner link)
if (objectCode !== objCode){
linkmetaObj.eachAttribute(function(attr, attrCode){
if (Ext.String.startsWith(attrCode, 'mi_', true )){
return true;
}
if (attr.dataType === 'Entity' && attrCode.toUpperCase() !== 'ID' && attr.associatedEntity === objCode){
lnkType = { linkType: 'relation', srcObj: objectCode,
srcProp: attrCode , destObj: objCode, destProp: 'ID' };
me.editor.graph.addEdge(me.createEdge(lnkType), null, cell, vertex );
}
}, me);
}
}, me);
},
createEdge: function(param){
/*
var e = new mxCell('');
e.setEdge(true);
var geo = new mxGeometry();
geo.relative = true;
e.setGeometry(geo);
e.setValue(param);
e.setStyle('edgeStyle=entityRelationEdgeStyle');
*/
var assoc, doc, node;
doc = mxUtils.createXmlDocument();
node = doc.createElement('ubObject');
node.setAttribute('linkType', param.linkType );
node.setAttribute('srcObj', param.srcObj );
node.setAttribute('srcProp', param.srcProp );
node.setAttribute('destObj', param.destObj );
node.setAttribute('destProp', param.destProp );
if (param.linkType === 'relation'){
assoc = new mxCell(node , new mxGeometry(0, 0, 0, 0),
'endArrow=open;endSize=10;startArrow=diamondThin;startSize=10;startFill=0;edgeStyle=orthogonalEdgeStyle;' );
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(80, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true;
/*
sourceLabel = new mxCell('0..n', new mxGeometry(-1, 0, 0, 0), 'resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10');
sourceLabel.geometry.relative = true;
sourceLabel.setConnectable(false);
sourceLabel.vertex = true;
assoc.insert(sourceLabel);
targetLabel = new mxCell('1', new mxGeometry(1, 0, 0, 0), 'resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10');
targetLabel.geometry.relative = true;
targetLabel.setConnectable(false);
targetLabel.vertex = true;
assoc.insert(targetLabel);
*/
}
// segmentEdgeStyle orthogonalEdgeStyle
if (param.linkType === 'inheritage'){
assoc = new mxCell(node, new mxGeometry(0, 0, 0, 0), 'endArrow=block;endSize=10;endFill=0;startArrow=oval;startFill=0;startSize=7;edgeStyle=segmentEdgeStyle;fillColor=#0B31D9;strokeColor=#0B31D9;');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(80, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true;
}
//assoc.setAttribute('label', param.attributeFrom);
return assoc;
},
initObjectTree: function(){
var ftree, me = this, store, detail = [], subsystems = {};
$App.domainInfo.eachEntity(function(objVal, objName){
var subsystem = objVal.modelName;
// var pos = objName.indexOf('_'), subsystem = objName;
// if (pos >= 0){
// subsystem = objName.substr(0,pos);
// }
var parentNode = subsystems[subsystem];
if (!parentNode){
parentNode = {text: subsystem , expanded: false, children: [], icon : null};
subsystems[subsystem] = parentNode;
detail.push(parentNode);
parentNode.children.push({text: objName , leaf: true, icon : null, objCode: objName});
} else {
parentNode.children.push({text: objName , leaf: true, icon : null, objCode: objName});
}
}, me);
ftree = { root: { expanded: true, children: detail } };
store = Ext.create('Ext.data.TreeStore', ftree );
me.objectTree = Ext.create('Ext.tree.Panel',{
title: UB.i18n('entities'),
//maxHeight: 300,
flex : 1,
singleExpand : true,
region:'north',
store: store,
rootVisible: false,
listeners: {
itemmousedown: function( sender, record, item, index, e /*, eOpts */){
if(record.isLeaf()){
var dragElm, dragE, itemE, fXY, basewindow ;
dragElm = document.createElement('DIV');
basewindow = me.getContainer().getEl(); // me.up('basewindow').getEl();
document.documentElement.appendChild(dragElm);
dragE = Ext.get(dragElm);
itemE = Ext.get(item);
dragElm.style.border = '1px solid black';
dragElm.style.opacity = 1;
dragElm.style.backgroundColor = "white";
dragE.setWidth(itemE.getWidth());
dragE.setHeight(itemE.getHeight());
fXY = e.getXY();
dragE.position("absolute", basewindow.dom.style.zIndex + 2, fXY[0] , fXY[1] );
me.dragDropObj = {objectName: record.get('text'), dragElm: dragElm };
}
},
scope: me
}
});
},
useBlobForData: true,
getDataBlob: function(){
var me = this;
if (!me.useBlobForData){
Ext.Error.raise('object does not use Blob');
}
return me.dataBlob;
},
updateDataBlob: function(inblob){
var me = this;
if (!me.useBlobForData){
Ext.Error.raise('object does not use Blob');
}
//debugger;
if (me.dataBlob && !Ext.isEmpty(this.objUrl)){
window.URL.revokeObjectURL(this.objUrl);
}
me.data = null;
me.dataBlob = inblob;
me.objUrl = window.URL.createObjectURL(inblob);
me.data = me.objUrl;
},
onDestroy: function () {
var me = this;
//debugger;
me.dataBlob = null;
me.data = null;
if (me.useBlobForData && !Ext.isEmpty(me.objUrl)){
window.URL.revokeObjectURL(me.objUrl);
}
me.objUrl = null;
this.callParent();
},
/**
*
* @param cfg
* @returns(Promise)
*/
setSrc: function(cfg) {
var
me = this,
data = cfg.url,
blobData = cfg.blobData,
doInit;
doInit = function(){
me.changeFired = true;
if(me.editor) {
me.isInitEditor = true;
try {
me.editor.open(me.objUrl);
} finally {
me.isInitEditor = false;
}
me.validateDiagram();
me.editor.setMode('select');
}
me.changeFired = false;
};
me.dataUrl = data;
if (me.useBlobForData){
if (blobData){
me.updateDataBlob(blobData);
doInit();
return Q.resolve(true);
} else {
return $App.connection.get(me.dataUrl, {responseType: "arraybuffer"})
.then(function(response){
var blobData, pdfArray = response.data;
blobData = new Blob(
[pdfArray],
{type: cfg.contentType}
);
me.updateDataBlob(blobData);
doInit();
}).fail(function(reason){
if (reason.status === 404){
if (cfg.onContentNotFound){
cfg.onContentNotFound();
} else {
UB.showErrorWindow('<span style="color: red">' + UB.i18n('documentNotFound') + '<span/>');
}
}
});
}
} else {
me.objUrl = me.dataUrl;
}
doInit();
return Q.resolve(true);
},
validateDiagram: function(){
var me = this , graph = me.editor.graph,
metaObj, metaObjRef, objCode, cellEdge,
srcObj , srcProp , destObj , destProp, linkType, lnkProp,
existProps = {}, deleteEdge, graphObject = {}, isInheritage, hasInheritage;
Ext.Object.each(me.editor.graph.model.cells, function(id,cell){
objCode = cell.getAttribute('objectCode');
if (!objCode){
return true;
}
graphObject[objCode.toLowerCase()] = cell;
});
Ext.Object.each(me.editor.graph.model.cells, function(id,cell){
objCode = cell.getAttribute('objectCode');
if (!objCode){
return true;
}
metaObj = $App.domainInfo.get(objCode);
// удаляем устаревшие элементы в схеме
if (!metaObj){
me.editor.graph.removeCells([cell], true);
return true;
}
hasInheritage = false;
for (var i = cell.getEdgeCount() - 1; i > -1; i--){
cellEdge = cell.getEdgeAt(i);
//srcObj: , srcProp: , destObj: , destProp:
srcObj = cellEdge.getAttribute('srcObj') || '';
srcProp = cellEdge.getAttribute('srcProp') || '';
destObj = cellEdge.getAttribute('destObj') || '';
destProp = cellEdge.getAttribute('destProp') || '';
linkType = cellEdge.getAttribute('linkType') || 'relation';
isInheritage = (linkType === 'inheritage');
deleteEdge = false;
switch (objCode){
case srcObj:
lnkProp = metaObj.attr(srcProp);
metaObjRef = $App.domainInfo.get(destObj);
if (isInheritage){
deleteEdge = !lnkProp ||
!(metaObj.mixins && metaObj.mixins.unity && /**metaObj.mixins.unity.enabled && **/
metaObj.mixins.unity.entity === destObj );
hasInheritage = !deleteEdge;
} else {
deleteEdge = !lnkProp || (lnkProp.dataType !== 'Entity') || (srcProp.toUpperCase() === 'ID') ||
(lnkProp.associatedEntity.toLowerCase() !== destObj.toLowerCase() ) ||
(Ext.String.startsWith(srcProp.toLowerCase(), 'mi_', true ));
}
deleteEdge = deleteEdge || !(graphObject[destObj.toLowerCase()]);
if (lnkProp){
existProps[srcProp] = lnkProp;
}
break;
case destObj:
lnkProp = metaObj.attr(destProp);
deleteEdge = !lnkProp ;
deleteEdge = deleteEdge || !(graphObject[srcObj.toLowerCase()]);
metaObjRef = $App.domainInfo.get(srcObj);
break;
default : lnkProp = null; deleteEdge = true;
}
if (!metaObjRef){
deleteEdge = true;
}
if (deleteEdge){
graph.model.beginUpdate();
try
{
graph.cellsRemoved([cellEdge]);
//graph.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS,
// 'cells', cells, 'includeEdges', null));
}
finally
{
graph.model.endUpdate();
}
}
}
// добавляем отсутствующие элементы в схеме
if (!hasInheritage && metaObj.mixins && metaObj.mixins.unity &&
/** metaObj.mixins.unity.enabled &&**/ graphObject[metaObj.mixins.unity.entity]){
var val = { linkType: 'inheritage', srcObj: objCode, srcProp: 'ID' , destObj: metaObj.mixins.unity.entity, destProp: 'ID' };
me.editor.graph.addEdge( me.createEdge(val), null, cell, graphObject[metaObj.mixins.unity.entity] );
}
Ext.Object.each(metaObj.attributes, function(attrCode, attr){
if (Ext.String.startsWith(attrCode, 'mi_', true )){
return true;
}
if (attr.dataType === 'Entity' && (attrCode.toUpperCase() !== 'ID') && graphObject[attr.associatedEntity.toLowerCase()] &&
!existProps[attrCode]){
var val = { linkType: 'relation', srcObj: objCode, srcProp: attrCode , destObj: attr.associatedEntity, destProp: 'ID' };
me.editor.graph.addEdge( me.createEdge(val), null, cell, graphObject[attr.associatedEntity.toLowerCase()] );
}
});
},me);
},
/**
* return either window or panel in which we born
* @return {Ext.container.Container}
*/
getContainer: function(){
return this.up('basewindow') || this.up('basepanel');
},
initMXEditor: function(){
var
config = mxUtils.load('resources/mxGraph/config/ubmetaeditor.xml' ).getDocumentElement(),
me = this, editor, graph, tdom, div, mainWin;
// workfloweditor.xml
mainWin = me.getContainer();
me.editor = editor = new mxEditor(config);
graph = editor.graph;
me.graphDivEl = Ext.get(me.containerId);
div = me.graphDivEl.dom;
editor.setGraphContainer(div);
(new Ext.Element(editor.toolbar.toolbar.container)).up('div.mxWindow').remove();
Ext.get(me.toolbarId).dom.appendChild(editor.toolbar.toolbar.container);
// key handler
/*
editor.keyHandler.handler.target = mainWin.getEl().dom;
*/
editor.keyHandler.handler.target = me.getEl().dom;
mxEvent.addListener(editor.keyHandler.handler.target, 'keydown', editor.keyHandler.handler.keydownHandler);
//graph.addListener(mxEvent.CELLS_REMOVED, Ext.bind(me.onCellRemoved,me));
//graph.addListener(mxEvent.REMOVE_CELLS, Ext.bind(me.onCellRemove,me));
editor.keyHandler.handler.isGraphEvent = function(evt){ return me.isGraphEvent( evt, this ); };
editor.setModified = function (value)
{
editor.modified = value;
if (value){
me.graphChanged();
}
};
graph.popupMenuHandler.factoryMethod =
mxUtils.bind(this, function(menu, cell, evt)
{
var frmDom = mainWin.getEl().dom;
menu.div.parent = frmDom;
menu.zIndex = frmDom.style.zIndex + 1;
menu.div.style.zIndex = frmDom.style.zIndex + 1;
//me.getel().style.zIndex;
return editor.createPopupMenu(menu, cell, evt);
});
me.initGraph();
editor.graph.cellsDisconnectable = false;
editor.graph.cellsCloneable = false;
editor.graph.allowDanglingEdges = false;
editor.graph.disconnectOnMove = false;
editor.showOutline();
var el = (new Ext.Element(editor.outline.div)).down('div.mxWindowPane');
Ext.get(me.outlineId).appendChild( el );
editor.outline.setVisible(false); //MPV - hide native outline control
editor._showTasks = editor.showTasks;
if (editor.tasks){
editor.tasks.destroy();
editor.tasks = null;
}
editor.showTasks = Ext.Function.bind(me.showTasks, me);
editor.refreshTasks = Ext.Function.bind(me.refreshTasks, me);
editor.properties = null;
editor.showProperties = Ext.Function.bind(me.showProperties, me);
editor.hideProperties = Ext.Function.bind(me.hideProperties, me);
/*
editor.addAction('toggleOutline', function(editor)
{
if (editor.outline === null) {
editor.showOutline();
} else {
editor.outline.setVisible(!editor.outline.isVisible());
}
});
*/
editor.addAction('edit', function(editorprm, cell /*, evt*/){
if (cell){
var objectCode = cell.getAttribute('objectCode');
if (objectCode){
me.showEntityForm(objectCode);
} else {
if (editor.graph.isEnabled() &&
editor.graph.isCellEditable(cell))
{
editor.graph.startEditingAtCell(cell);
}
}
}
});
graph.getTooltipForCell = me.getTooltipForCell;
graph.tooltipHandler.zIndex = mainWin.getEl().dom.style.zIndex + 1;
graph.setResizeContainer(true);
//graph.setEnabled(false);
// Enables rubberband selection
/*jshint nonew: false */
new mxRubberband(graph);
/*jshint nonew: true */
graph.setPanning(true);
graph.setTooltips(true);
if( me.objUrl) {
me.isInitEditor = true;
try {
me.editor.open(me.objUrl);
} finally {
me.isInitEditor = false;
}
}
},
showEntityForm: function(entityCode){
var me = this, storeData, mixData, entity, edtAttr, edtMixin, onTextFieldChange, gridProp;
if (!me.editEntityFrm){
/*
Ext.define('M1Attributes',{
extend: 'Ext.data.Model',
fields: [
{name :'code', type: 'string'},
{name :'caption',type: 'string'},
{name :'dataType',type: 'string'},
{name :'associatedEntity',type: 'string'},
{name :'accessType',type: 'string'},
{name :'allowNull',type: 'string'},
{name :'isUnique',type: 'string'},
{name :'defaultValue', type: 'string'},
{name :'allowSort', type: 'string'}
]
});*/
storeData = Ext.create('Ext.data.Store', {
fields:['code', 'caption', 'size', 'dataType', 'associatedEntity', 'accessType', 'allowNull', 'isUnique', 'defaultValue', 'allowSort'],
data : {attributes: [{}]}, // colData,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'attributes'
}
}
});
mixData = Ext.create('Ext.data.Store', {
fields:['icon', 'code', 'enabled'],
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'mixins'
}
}
});
me.editEntityFrm = Ext.create('UB.view.BaseWindow', {
title: 'Entity',
height: 500,
width: 600,
closeAction : 'hide',
autoDestroy: false,
modal: true,
stateful: true,
stateId: "ubMetaDiagrm_entityform",
layout: { type: 'border' },
//layout: {
// type: 'hbox',
// align: 'stretch'
//},
items: [
{
xtype: 'tabpanel',
deferredRender: false,
region:'center',
//split: true,
items: [
{
//height: 'auto',
title: UB.i18n('AsTаble'),
layout: { type: "border" },
items: [
gridProp = Ext.create('Ext.grid.Panel',
{
//xtype: 'gridpanel',
tbar: ['Search',{
xtype: 'textfield',
name: 'searchField',
hideLabel: true,
width: 200,
listeners: {
change: {
fn: function(){ onTextFieldChange(this); },
buffer: 100
}
}
}
],
region:'center',
split: true,
//height: '100%',
//width: '100%',
itemId: 'colGrid',
flex: 1,
title: UB.i18n('Attributes'),
store: storeData,
columns: [
{ text: UB.i18n('code'), dataIndex: 'code' },
{ text: UB.i18n('caption'), dataIndex: 'caption' },
{ text: UB.i18n('dataType'), dataIndex: 'dataType' },
{ text: UB.i18n('size'), width: 60, dataIndex: 'size' },
{ text: UB.i18n('associatedEntity'), dataIndex: 'associatedEntity' },
{ text: UB.i18n('accessType'), dataIndex: 'accessType' },
{ text: UB.i18n('allowNull'), width: 50, dataIndex: 'allowNull' },
{ text: UB.i18n('isUnique'), width: 50, dataIndex: 'isUnique' },
{ text: UB.i18n('defaultValue'), dataIndex: 'defaultValue' },
{ text: UB.i18n('allowSort'), width: 50, dataIndex: 'allowSort' }
],
listeners:{
select: function( grd, record/*, index, eOpts*/ ){
var prop = me.editEntityFrmEditor.selEntity.attributes[record.get('code')];
edtAttr.setValue( record.get('code') + ' = \r\n' + js_beautify(JSON.stringify(
prop.asJSON()
)));
},
scope: me
}
}),
{
xtype: "ubcodemirror",
mode: "application/x-javascript",
itemId: 'edtAttr',
width: 250,
region:'east',
showLineNumbers: false,
split: true
},
{
height: 120,
region:'south',
layout: { type: "border" },
split: true,
items:[
{
xtype: 'gridpanel',
region:'center',
split: true,
itemId: 'mixGrid',
flex: 1,
title: UB.i18n('Mixins'),
store: mixData,
columns: [
{ text: '-', dataIndex: 'icon' },
{ text: UB.i18n('code'), dataIndex: 'code' },
{ text: UB.i18n('enabled'), dataIndex: 'enabled' }
],
listeners:{
select: function( grd, record/*, index, eOpts */){
edtMixin.setValue( record.get('code') + ' = \r\n' + js_beautify(JSON.stringify(
me.editEntityFrmEditor.selEntity.mixins[record.get('code')])));
},
scope: me
}
},
{
xtype: "ubcodemirror",
mode: "application/x-javascript",
itemId: 'edtMixin',
width: 250,
region:'east',
showLineNumbers: false,
split: true
}
]
}
]
},
{
itemId: 'myEditor',
xtype: "ubcodemirror",
mode: "application/x-javascript",
title: UB.i18n('AsJSON'),
//flex: 1,
height: '100%',
style: {
background: "white"
},
hideLabel: false /*, labelAlign: "top"*/
}
]
}
]
});
me.editEntityFrmEditor = me.editEntityFrm.down('[itemId=myEditor]'); // me.editEntityFrm.getComponent('myEditor');
me.editEntityFrmEditor.fColGrd = me.editEntityFrm.down('[itemId=colGrid]'); //me.editEntityFrm.getComponent('columnGrid');
me.editEntityFrmEditor.fmixGrid = me.editEntityFrm.down('[itemId=mixGrid]');
edtAttr = me.editEntityFrm.down('[itemId=edtAttr]');
edtMixin = me.editEntityFrm.down('[itemId=edtMixin]');
onTextFieldChange = function(tbox){
var store = gridProp.getStore();
var value = tbox.getValue();
store.clearFilter(true);
var valueftr = new RegExp(value, 'i');
store.filter([
{filterFn: function(item) {
return valueftr.test(item.get("code")) ||
valueftr.test(item.get("caption")) ||
valueftr.test(item.get("dataType")) ||
valueftr.test(item.get("associatedEntity")) ||
valueftr.test(item.get("size")) ||
valueftr.test(item.get("accessType")) ;
}}
]);
};
}
entity = $App.domainInfo.get(entityCode);
me.editEntityFrmEditor.selEntity = entity;
if (entity){
me.editEntityFrmEditor.setValue( js_beautify(JSON.stringify(entity.asJSON())) );
var colData = [];
entity.eachAttribute( function(row, code){
var dat = Ext.clone(row);
dat.code = code;
colData.push(dat);
}
);
var mixinData = [];
Ext.Object.each(entity.mixins, function(code, row){
var dat = Ext.clone(row);
dat.code = code;
dat.icon = UB.ux.UBMetaDiagram.mixinPictures[code] || code;
mixinData.push(dat);
}
);
me.editEntityFrm.setTitle(entityCode );
me.editEntityFrmEditor.fColGrd.getStore().loadRawData( {attributes: colData}, false);
me.editEntityFrmEditor.fmixGrid.getStore().loadRawData( {mixins: mixinData}, false);
me.editEntityFrm.down('[itemId=edtAttr]').setValue(' ');
me.editEntityFrm.down('[itemId=edtMixin]').setValue(' ');
me.editEntityFrm.show();
}
},
// .isGraphEvent = function(evt)
isGraphEvent: function(evt, handler){
var source = mxEvent.getSource(evt);
// Accepts events from the target object or
// in-place editing inside graph
if ((source === handler.target || source.parentNode === handler.target ) ||
(handler.graph.cellEditor !== null && source === handler.graph.cellEditor.textarea))
{
return true;
}
// in edit form
var elt = source;
while (elt !== null)
{
if (elt === handler.target)
{
return true;
}
elt = elt.parentNode;
}
// Accepts events from inside the container
elt = source;
while (elt !== null)
{
if (elt === handler.graph.container)
{
return true;
}
elt = elt.parentNode;
}
return false;
},
/*
onCellRemove: function(graph, eventObject){
var me = this, cells = eventObject.properties.cells;
Ext.Array.each(cells,function(cell,index){
var srcProp = cell.getAttribute('objectCode');
if (!srcProp){
return true;
}
var edges = graph.getAllEdges([cell]);
me.inProcessRemoveEdge = true;
try
{
graph.removeCells(edges);
} finally {
me.inProcessRemoveEdge = false;
}
//graph.
//Ext.Error.raise('It is impossible to remove the object links!');
},me);
},
onCellRemoved: function(cells){
Ext.Array.each(cells,function(cell,index){
var objCode = cell.getAttribute('objectCode');
if (!objCode){
return true;
}
},this);
},
*/
getTooltipForCell: function(cell){
var attr, obj;
if ((attr = cell.getAttribute('objectCode'))){
obj = $App.domainInfo.get(attr);
return obj.caption + ': ' + obj.description;
}
if ((attr = cell.getAttribute('srcProp'))){
if ((cell.getAttribute('linkType') || 'relation') === 'relation'){
return cell.getAttribute('srcObj') + '.' + attr + ' -> ' + cell.getAttribute('destObj') + '.' + cell.getAttribute('destProp');
} else {
return cell.getAttribute('srcObj') + ' inherit ' + cell.getAttribute('destObj') ;
}
}
},
graphChanged : function(){
var me = this;
//if (!me.changeFired){
//var objVal = Ext.JSON.decode(this.initialValue);
//objVal.forDirtyRecord= true;
//this.initialValue = Ext.JSON.encode(objVal);
if (!me.isInitEditor){
this.fireEvent('change', this);
}
//}
//me.changeFired =true;
},
initGraph: function(){
var me = this, editor = me.editor, graph = editor.graph;
// Enables rotation handle
mxVertexHandler.prototype.rotationEnabled = true;
// Enables managing of sizers
mxVertexHandler.prototype.manageSizers = true;
// Enables live preview
mxVertexHandler.prototype.livePreview = true;
// Enables guides
//mxGraphHandler.prototype.guidesEnabled = true;
graph.graphHandler.guidesEnabled = true;
//graph.defaultLoopStyle = mxEdgeStyle.EntityRelation;
graph.allowLoops = true;
graph.isHtmlLabel = function(cell){
var state = graph.view.getState(cell);
var style = (state) ? state.style : graph.getCellStyle(cell);
return style.html + '' === '1' || style.whiteSpace + '' === 'wrap';
};
// HTML entities are displayed as plain text in wrapped plain text labels
graph.cellRenderer.getLabelValue = function(state){
var result = mxCellRenderer.prototype.getLabelValue.apply(graph.cellRenderer, arguments);
if (state.style.whiteSpace + '' === 'wrap' && state.style.html + '' !== '1')
{
result = mxUtils.htmlEntities(result, false);
}
return result;
};
graph.convertValueToString = function(cell){
if (Ext.isString(cell.value)) {
return cell.value;
} else {
if ( !Ext.isEmpty(cell.getAttribute('objectCode')) ){
return me.generateObjHtml(cell);
} else {
return cell.getAttribute('label');
}
}
};
//.removeCells = function(cells, includeEdges)
var oldRemoveCells = graph.removeCells;
graph.removeCells = function(cells, includeEdges){
if (!cells){
cells = graph.getDeletableCells(graph.getSelectionCells());
}
var index = cells.length - 1;
while(index > -1){
var srcProp = cells[index].getAttribute('srcProp');
if (srcProp){
cells.splice(index,1);
}
index--;
}
oldRemoveCells.call(graph, cells, includeEdges );
};
/*
var BaseisCellDeletable = graph.isCellDeletable;
graph.isCellDeletable = function(cell)
{
var srcProp = cell.getAttribute('srcProp');
return (!srcProp || me.inProcessRemoveEdge) && BaseisCellDeletable.call(graph, cell);
};
*/
},
generateObjHtml: function(cell){
var me = this, ubObj, objectCode, htmlt, isEntity, ftype;
objectCode = cell.getAttribute('objectCode');
if (!me.htmCache){
me.htmCache ={};
}
//if ((htmlt = me.htmCache[objectCode + cell.getId()])){
// return htmlt;
///}
//'<div style="overflow-y:scrol">', </div> e4e4e4 overflow-y:scrol opacity:1; width:100%; height:100%;
htmlt = [
//'<div style="overflow: hidden; font-size:12px; -moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;">',
//'<div style="width:100%; height=100px; overflow-y: hidden;" >',
'<table width="100%" height="100%" style=" -moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;" >',
'<tr><td style="vertical-align: top;" ><div >' , // style="overflow: hidden; height:',cell.geometry.height - 25,'px "
'<table style="width:100%;" >' ,
'<tr><td colspan="2" style="text-align:center; background:#C1D3F5;padding:2px;">' , objectCode , '</td></tr>'
];
ubObj = $App.domainInfo.get(objectCode);
ubObj.eachAttribute(function(attr, attrCode){
if (Ext.String.startsWith(attrCode, 'mi_', true )){
return true;
}
isEntity = attr.dataType === 'Entity';
ftype = attr.dataType === 'Enum' ? 'Enum ' + attr.enumGroup + '':
(isEntity ? '<B>' + attr.associatedEntity + '</B>' : attr.dataType );
htmlt.push('<tr><td>',attrCode ,'</td><td style="padding:2px;">', ftype, '</td></tr>');
});
// Add mixins images
var cellMixinImages = [];
_.forEach(ubObj.mixins, function(mixinConfig, mixinName){
if (mixinConfig.enabled){
cellMixinImages.push(UB.ux.UBMetaDiagram.mixinPictures[mixinName] || mixinName);
}
});
if (cellMixinImages.length){
htmlt.push('<tr><td colspan="2" style="text-align:center; background:#C1D3F5;padding:2px;">' + cellMixinImages.join(' ') + '</td></tr>');
}
htmlt.push('</table></div></td></tr></table>');
/*
htmlt.push('</table></div></td></tr><tr><td style="text-align:center;vertical-align: bottom;border-top: 1px solid #DBDBDB;" >');
htmlt.push('mixins ');
Ext.Object.each(ubObj.mixins, function(mixinCode, mixin){
htmlt.push( me.getMixinShortName(mixinCode)+ ' ' );
},me);
htmlt.push('</td></tr></table>');
*/
return htmlt.join('');
},
getMixinShortName: function(mixinCode){
if (mixinCode === 'mStorage'){
return 'S';
} else
{
return mixinCode.substr(0,1).toUpperCase();
}
},
refreshTasks: function (div){
var me = this;
if (this.tasks !== null)
{
//var div = this.tasks.content;
//mxEvent.release(div);
me.taskEl.innerHTML = '';
me.taskEl.createTasks(div);
}
},
showTasks: function(){
var me = this, taskWnd, graph = me.editor.graph,
taskPnl, taskEl;
if (me.editor.tasks === null)
{
var div = document.createElement('div');
div.style.padding = '4px';
div.style.paddingLeft = '20px';
//var w = document.body.clientWidth;
taskPnl = Ext.widget('panel', {
border: true,
flex: 1
});
taskWnd = Ext.create('Ext.Window', {
title: 'Tasks',
width: 200,
height: 400,
closable: true,
closeAction : 'hide',
autoDestroy: false,
layout: 'fit',
items:[
taskPnl
]
}).show();
me.taskWnd = taskWnd;
taskWnd.ownerCt = me;
taskWnd.registerWithOwnerCt();
var tdom = taskPnl.getEl().dom;
document.getElementById(tdom.id + '-innerCt').appendChild(div);
me.taskEl = taskEl = div;
/*
var wnd = new mxWindow(
mxResources.get(this.tasksResource) ||
this.tasksResource,
div, w - 220, this.tasksTop, 200);
wnd.setClosable(true);
wnd.destroyOnClose = false;
*/
// Installs a function to update the contents
// of the tasks window on every change of the
// model, selection or root.
var funct = mxUtils.bind(me, function(/*sender*/){
//mxEvent.release(div);
me.taskEl.innerHTML = '';
me.editor.createTasks(me.taskEl);
});
graph.getModel().addListener(mxEvent.CHANGE, funct);
graph.getSelectionModel().addListener(mxEvent.CHANGE, funct);
graph.addListener(mxEvent.ROOT, funct);
me.editor.tasks = taskWnd;
//debugger;
me.editor.createTasks(div);
}
me.taskWnd.show();
},
showProperties: function (cell){
var
me = this,
editor = me.editor;
cell = cell || editor.graph.getSelectionCell();
// Uses the root node for the properties dialog
// if not cell was passed in and no cell is
// selected
if (cell === null)
{
cell = editor.graph.getCurrentRoot();
if (cell === null)
{
cell = editor.graph.getModel().getRoot();
}
}
if (cell !== null)
{
// Makes sure there is no in-place editor in the
// graph and computes the location of the dialog
editor.graph.stopEditing(true);
// var offset = mxUtils.getOffset(editor.graph.container);
// var x = offset.x+10;
// var y = offset.y;
/*
// Avoids moving the dialog if it is alredy open
if (editor.properties !== null && !editor.movePropertiesDialog)
{
x = editor.properties.getX();
y = editor.properties.getY();
}
// Places the dialog near the cell for which it
// displays the properties
else
{
var bounds = editor.graph.getCellBounds(cell);
if (bounds != null)
{
x += bounds.x+Math.min(200, bounds.width);
y += bounds.y;
}
}
*/
// Hides the existing properties dialog and creates a new one with the
// contents created in the hook method
editor.hideProperties();
var node = editor.createProperties(cell);
if (node !== null)
{
// Displays the contents in a window and stores a reference to the
// window for later hiding of the window
var propPnl = Ext.widget('panel', {
border: true,
flex: 1
});
var propWnd = Ext.create('Ext.Window', {
title: 'Properties',
width: 250,
height: 400,
closable: false,
//closeAction : 'hide',
//autoDestroy: false,
layout: 'fit',
items:[
propPnl
]
}).show();
//me.taskWnd = taskWnd;
propWnd.ownerCt = me;
propWnd.registerWithOwnerCt();
var tdom = propPnl.getEl().dom;
document.getElementById(tdom.id + '-innerCt').appendChild(node);
editor.properties = propWnd;
//this.properties = new mxWindow(mxResources.get(this.propertiesResource) ||
// this.propertiesResource, node, x, y, this.propertiesWidth, this.propertiesHeight, false);
//this.properties.setVisible(true);
}
}
},
hideProperties: function (){
var
me = this,
editor = me.editor, cell;
if (editor.properties !== null)
{
editor.properties.close();
editor.properties = null;
}
},
beforeDestroy: function(){
var
me = this;
if (me.editor) { me.editor.destroy();}
if (me.tasksWnd) { me.tasksWnd.destroy(); }
me.editEntityFrmEditor = null;
if (me.editEntityFrm) {me.editEntityFrm.destroy();}
Ext.EventManager.un(document, 'onmouseup', me.onmouseUpFunc ,me);
Ext.EventManager.un(document, 'onmousemove', me.onmousemoveFunc ,me);
me.callParent(arguments);
},
actionHandler: function(sender){
this.editor.execute(sender.mxAction);
},
getValue: function(){
var me = this, enc = new mxCodec(),
data = enc.encode(me.editor.graph.getModel());
return mxUtils.getXml(data);
//return this.initialValue;
},
resetOriginalValue : function(){
return null;
}
}
);