All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.dirigible.ide-schema.js.editor.js Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2024 Eclipse Dirigible contributors
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * SPDX-FileCopyrightText: Eclipse Dirigible contributors
 * SPDX-License-Identifier: EPL-2.0
 */
angular.module('ui.schema.modeler', ["ideUI", "ideView", "ideWorkspace"])
	.controller('ModelerCtrl', function ($scope, messageHub, workspaceApi, $window, ViewParameters) {
		let contents;
		let schemaFile;
		$scope.errorMessage = 'An unknown error was encountered. Please see console for more information.';
		$scope.forms = {
			editor: {},
		};
		$scope.state = {
			isBusy: true,
			error: false,
			busyText: "Loading...",
		};
		$scope.dataTypes = [
			{ value: "VARCHAR", label: "VARCHAR" },
			{ value: "CHAR", label: "CHAR" },
			{ value: "DATE", label: "DATE" },
			{ value: "TIME", label: "TIME" },
			{ value: "TIMESTAMP", label: "TIMESTAMP" },
			{ value: "INTEGER", label: "INTEGER" },
			{ value: "TINYINT", label: "TINYINT" },
			{ value: "BIGINT", label: "BIGINT" },
			{ value: "SMALLINT", label: "SMALLINT" },
			{ value: "REAL", label: "REAL" },
			{ value: "DOUBLE", label: "DOUBLE" },
			{ value: "BOOLEAN", label: "BOOLEAN" },
			{ value: "BLOB", label: "BLOB" },
			{ value: "DECIMAL", label: "DECIMAL" },
			{ value: "BIT", label: "BIT" },
		];

		angular.element($window).bind("focus", function () {
			messageHub.setFocusedEditor($scope.dataParameters.file);
			messageHub.setStatusCaret('');
		});

		$scope.showAlert = function (title, message) {
			messageHub.showAlertError(title, message);
		};

		function initializeSchemaJson() {
			workspaceApi.createNode('', schemaFile, false, '').then(function (response) {
				if (response.status === 201) {
					const fileDescriptor = {
						name: schemaFile.substring(schemaFile.lastIndexOf('/') + 1),
						path: schemaFile.substring(schemaFile.indexOf('/', 1)),
						contentType: $scope.dataParameters.contentType,
						workspace: schemaFile.substring(1, schemaFile.indexOf('/', 1)),
					};
					messageHub.announceFileSaved(fileDescriptor);
					messageHub.setStatusMessage(`File '${schemaFile}' created`);
					messageHub.postMessage('projects.tree.refresh', { partial: true, project: fileDescriptor.path.substring(1, fileDescriptor.path.indexOf('/', 1)), workspace: fileDescriptor.workspace }, true);
				} else {
					messageHub.setStatusError(`Error saving '${schemaFile}'`);
					messageHub.showAlertError('Error while saving the file', 'Please look at the console for more information');
					$scope.state.isBusy = false;
				}
			});
		}

		function saveContents(text, resourcePath) {
			workspaceApi.saveContent('', resourcePath, text).then(function (response) {
				if (response.status === 200) {
					messageHub.announceFileSaved({
						name: resourcePath.substring(resourcePath.lastIndexOf('/') + 1),
						path: resourcePath.substring(resourcePath.indexOf('/', 1)),
						contentType: $scope.dataParameters.contentType,
						workspace: resourcePath.substring(1, resourcePath.indexOf('/', 1)),
					});
					messageHub.setStatusMessage(`File '${resourcePath}' saved`);
					messageHub.setEditorDirty(resourcePath, false);
					$scope.$apply(function () {
						$scope.state.isBusy = false;
					});
				} else {
					messageHub.setStatusError(`Error saving '${resourcePath}'`);
					messageHub.showAlertError('Error while saving the file', 'Please look at the console for more information');
					$scope.$apply(function () {
						$scope.state.isBusy = false;
					});
				}
			});
		}

		$scope.checkSchema = function () {
			workspaceApi.resourceExists(schemaFile).then(function (response) {
				if (response.status !== 200) initializeSchemaJson();
			});
		};

		$scope.load = function () {
			if (!$scope.state.error) {
				workspaceApi.loadContent('', $scope.dataParameters.file).then(function (response) {
					if (response.status === 200) {
						contents = response.data;
						$scope.checkSchema();
						main(document.getElementById('graphContainer'),
							document.getElementById('outlineContainer'),
							document.getElementById('toolbarContainer'),
							document.getElementById('sidebarContainer'));
						$scope.$apply(() => $scope.state.isBusy = false);
					} else if (response.status === 404) {
						messageHub.closeEditor($scope.dataParameters.file);
					} else {
						$scope.$apply(function () {
							$scope.state.error = true;
							$scope.errorMessage = 'There was a problem with loading the file';
							$scope.state.isBusy = false;
						});
					}
				});
			}
		};

		$scope.saveSchema = function () {
			saveContents(createSchema($scope.graph), $scope.dataParameters.file);
			saveContents(createSchemaJson($scope.graph), schemaFile);
		};

		$scope.getBoolean = function (value) {
			if (typeof value === "string") {
				if (value === "true") return true;
				return false;
			} else if (typeof value === "number") {
				if (value === 1) return true;
				else return false;
			} else if (typeof value === "boolean") return value;
			return false;
		};

		messageHub.onEditorFocusGain(function (msg) {
			if (msg.resourcePath === $scope.dataParameters.file) messageHub.setStatusCaret('');
		});

		messageHub.onEditorReloadParameters(
			function (event) {
				$scope.$apply(() => {
					if (event.resourcePath === $scope.dataParameters.file) {
						$scope.dataParameters = ViewParameters.get();
					}
				});
			}
		);

		messageHub.onDidReceiveMessage(
			"editor.file.save.all",
			function () {
				if (!$scope.state.error) {
					$scope.saveSchema();
				}
			},
			true,
		);

		messageHub.onDidReceiveMessage(
			"editor.file.save",
			function (msg) {
				if (!$scope.state.error) {
					let file = msg.data && typeof msg.data === 'object' && msg.data.file;
					if (file && file === $scope.dataParameters.file) {
						$scope.saveSchema();
					}
				}
			},
			true,
		);

		messageHub.onDidReceiveMessage(
			"dsmEditor.schema.sql",
			function () {
				messageHub.hideFormDialog("dsmSchemaSQL");
			},
			true
		);

		messageHub.onDidReceiveMessage(
			"dsmEditor.table.properties",
			function (msg) {
				if (msg.data.buttonId === "b1") {
					let cell = $scope.graph.model.getCell(msg.data.formData[0].id.substring(5));
					cell.value.name = msg.data.formData[0].value;
					$scope.graph.model.setValue(cell, cell.value);
				}
				messageHub.hideFormDialog("dsmTableProperties");
			},
			true
		);

		messageHub.onDidReceiveMessage(
			"dsmEditor.column.sqlproperties",
			function (msg) {
				if (msg.data.buttonId === "b1") {
					// Maybe we should do this with "cell.value.clone()'
					let cell = $scope.graph.model.getCell(msg.data.formData[0].id.substring(5));
					cell.value.name = msg.data.formData[0].value;
					$scope.graph.model.setValue(cell, cell.value);
				}
				messageHub.hideFormDialog("dsmColumnSQLProperties");
			},
			true
		);

		messageHub.onDidReceiveMessage(
			"dsmEditor.column.properties",
			function (msg) {
				if (msg.data.buttonId === "b1") {
					// Maybe we should do this with "cell.value.clone()'
					let cell = $scope.graph.model.getCell(msg.data.formData[0].id.substring(5));
					cell.value.name = msg.data.formData[0].value;
					cell.value.type = msg.data.formData[1].value;
					cell.value.columnLength = msg.data.formData[2].value;
					cell.value.primaryKey = `${msg.data.formData[3].value}`;
					cell.value.autoIncrement = `${msg.data.formData[4].value}`;
					cell.value.notNull = `${msg.data.formData[5].value}`;
					cell.value.unique = `${msg.data.formData[6].value}`;
					cell.value.precision = msg.data.formData[7].value;
					cell.value.scale = msg.data.formData[8].value;
					cell.value.defaultValue = msg.data.formData[9].value;
					$scope.graph.model.setValue(cell, cell.value);
				}
				messageHub.hideFormDialog("dsmColumnProperties");
			},
			true
		);

		function main(container, outline, toolbar, sidebar) {
			if (!mxClient.isBrowserSupported()) {
				mxUtils.error('Browser is not supported!', 200, false);
				$scope.state.error = true;
				$scope.errorMessage = "Your browser is not supported with this editor!";
			} else {
				// Specifies shadow opacity, color and offset
				mxConstants.SHADOW_OPACITY = 0.5;
				mxConstants.SHADOWCOLOR = '#C0C0C0';
				mxConstants.SHADOW_OFFSET_X = 0;
				mxConstants.SHADOW_OFFSET_Y = 0;

				// Table icon dimensions and position
				mxSwimlane.prototype.imageSize = 20;
				mxSwimlane.prototype.imageDx = 16;
				mxSwimlane.prototype.imageDy = 4;

				// Changes swimlane icon bounds
				mxSwimlane.prototype.getImageBounds = function (x, y, w, h) {
					return new mxRectangle(x + this.imageDx, y + this.imageDy, this.imageSize, this.imageSize);
				};

				// Defines an icon for creating new connections in the connection handler.
				// This will automatically disable the highlighting of the source vertex.
				mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);

				// Workaround for Internet Explorer ignoring certain CSS directives
				if (mxClient.IS_QUIRKS) {
					document.body.style.overflow = 'hidden';
					new mxDivResizer(container);
					new mxDivResizer(outline);
					new mxDivResizer(toolbar);
					new mxDivResizer(sidebar);
				}

				// Creates the graph inside the given container. The
				// editor is used to create certain functionality for the
				// graph, such as the rubberband selection, but most parts
				// of the UI are custom in this example.
				let editor = new mxEditor();
				$scope.graph = editor.graph;

				initClipboard($scope.graph);

				// Disables some global features
				$scope.graph.setConnectable(true);
				$scope.graph.setCellsDisconnectable(false);
				$scope.graph.setCellsCloneable(false);
				$scope.graph.swimlaneNesting = false;
				$scope.graph.dropEnabled = true;

				// Does not allow dangling edges
				$scope.graph.setAllowDanglingEdges(false);

				// Forces use of default edge in mxConnectionHandler
				$scope.graph.connectionHandler.factoryMethod = null;

				// Only tables are resizable
				$scope.graph.isCellResizable = function (cell) {
					return this.isSwimlane(cell);
				};

				// Only tables are movable
				$scope.graph.isCellMovable = function (cell) {
					return this.isSwimlane(cell);
				};

				// Sets the graph container and configures the editor
				editor.setGraphContainer(container);
				let config = mxUtils.load(
					'editors/config/keyhandler-minimal.xml').
					getDocumentElement();
				editor.configure(config);

				// Configures the automatic layout for the table columns
				editor.layoutSwimlanes = true;
				editor.createSwimlaneLayout = function () {
					let layout = new mxStackLayout($scope.graph, false);
					layout.fill = true;
					layout.resizeParent = true;

					// Overrides the function to always return true
					layout.isVertexMovable = function () {
						return true;
					};

					return layout;
				};

				// Text label changes will go into the name field of the user object
				$scope.graph.model.valueForCellChanged = function (cell, value) {
					if (value.name != null) {
						return mxGraphModel.prototype.valueForCellChanged.apply(this, arguments);
					}
					let old = cell.value.name;
					cell.value.name = value;
					return old;
				};

				// Columns are dynamically created HTML labels
				$scope.graph.isHtmlLabel = function (cell) {
					return !this.isSwimlane(cell) &&
						!$scope.graph.model.isEdge(cell);
				};

				// Edges are not editable
				$scope.graph.isCellEditable = function (cell) {
					return !$scope.graph.model.isEdge(cell);
				};

				// Returns the name field of the user object for the label
				$scope.graph.convertValueToString = function (cell) {
					if (cell.value != null && cell.value.name != null) {
						return cell.value.name;
					}

					return mxGraph.prototype.convertValueToString.apply(this, arguments); // "supercall"
				};

				// Returns the type as the tooltip for column cells
				$scope.graph.getTooltip = function (state) {
					if (this.isHtmlLabel(state.cell)) {
						return 'Type: ' + state.cell.value.type;
					} else if ($scope.graph.model.isEdge(state.cell)) {
						let source = $scope.graph.model.getTerminal(state.cell, true);
						let parent = $scope.graph.model.getParent(source);

						return parent.value.name + '.' + source.value.name;
					}

					return mxGraph.prototype.getTooltip.apply(this, arguments); // "supercall"
				};

				// Creates a dynamic HTML label for column fields
				$scope.graph.getLabel = function (cell) {
					if (this.isHtmlLabel(cell)) {
						let label = '';
						if (cell.value.primaryKey === 'true') {
							label += '';
						} else {
							label += '';
						}
						if (cell.value.autoIncrement === 'true') {
							label += '';
						} else if (cell.value.unique === 'true') {
							label += '';
						} else {
							label += '';
						}
						let suffix = ': ' + mxUtils.htmlEntities(cell.value.type, false) + (cell.value.columnLength ?
							'(' + cell.value.columnLength + ')' : '');
						suffix = cell.value.isSQL ? '' : suffix;
						return label + mxUtils.htmlEntities(cell.value.name, false) + suffix;
					}

					return mxGraph.prototype.getLabel.apply(this, arguments); // "supercall"
				};

				// Removes the source vertex if edges are removed
				$scope.graph.addListener(mxEvent.REMOVE_CELLS, function (sender, evt) {
					let cells = evt.getProperty('cells');
					for (let i = 0; i < cells.length; i++) {
						let cell = cells[i];
						if ($scope.graph.model.isEdge(cell)) {
							let terminal = $scope.graph.model.getTerminal(cell, true);
							// let parent = $scope.graph.model.getParent(terminal);
							$scope.graph.model.remove(terminal);
						}
					}
				});

				// Disables drag-and-drop into non-swimlanes.
				$scope.graph.isValidDropTarget = function (cell, cells, evt) {
					return this.isSwimlane(cell);
				};

				// Installs a popupmenu handler using local function (see below).
				$scope.graph.popupMenuHandler.factoryMethod = function (menu, cell, evt) {
					createPopupMenu(editor, $scope.graph, menu, cell, evt);
				};

				// Adds all required styles to the graph (see below)
				configureStylesheet($scope.graph);

				// Adds sidebar icon for the table object
				let tableObject = new Table('TABLENAME');
				let table = new mxCell(tableObject, new mxGeometry(0, 0, 200, 28), 'table');

				table.setVertex(true);
				addSidebarIcon($scope.graph, sidebar, table, 'sap-icon--table-view', 'Drag this to the diagram to create a new Table', $scope);

				// Adds sidebar icon for the column object
				let columnObject = new Column('COLUMNNAME');
				let column = new mxCell(columnObject, new mxGeometry(0, 0, 0, 26));

				column.setVertex(true);
				column.setConnectable(false);

				addSidebarIcon($scope.graph, sidebar, column, 'sap-icon--table-column', 'Drag this to a Table to create a new Column', $scope);

				// Adds sidebar icon for the view object
				let viewObject = new View('VIEWENAME');
				let view = new mxCell(viewObject, new mxGeometry(0, 0, 200, 28), 'view');

				view.setVertex(true);
				addSidebarIcon($scope.graph, sidebar, view, 'sap-icon--border', 'Drag this to the diagram to create a new View', $scope);

				// Adds primary key field into table
				let firstColumn = column.clone();

				firstColumn.value.name = 'TABLENAME_ID';
				firstColumn.value.type = 'INTEGER';
				firstColumn.value.columnLength = 0;
				firstColumn.value.primaryKey = 'true';
				firstColumn.value.autoIncrement = 'true';

				table.insert(firstColumn);

				// Adds sql field into view
				let sqlColumn = column.clone();

				sqlColumn.value.name = 'SELECT ...';
				sqlColumn.value.isSQL = true;

				view.insert(sqlColumn);

				// Adds child columns for new connections between tables
				$scope.graph.addEdge = function (edge, parent, source, target, index) {
					// check whether the source is view
					if (source.value.type === 'VIEW') {
						showAlert('Drop', 'Source must be a Table not a View', $scope);
						return;
					}
					// Finds the primary key child of the target table
					let primaryKey = null;
					let childCount = $scope.graph.model.getChildCount(target);

					for (let i = 0; i < childCount; i++) {
						let child = $scope.graph.model.getChildAt(target, i);
						if (child.value.primaryKey) {
							primaryKey = child;
							break;
						}
					}

					if (primaryKey.value.primaryKey !== 'true') {
						showAlert('Drop', 'Target Table must have a Primary Key', $scope);
						return;
					}

					$scope.graph.model.beginUpdate();
					try {
						let col1 = $scope.graph.model.cloneCell(column);
						col1.value.name = primaryKey.value.name;
						col1.value.type = primaryKey.value.type;
						col1.value.columnLength = primaryKey.value.columnLength;
						this.addCell(col1, source);
						source = col1;
						target = primaryKey;
						return mxGraph.prototype.addEdge.apply(this, arguments); // "supercall"
					} finally {
						$scope.graph.model.endUpdate();
					}
				};

				// Creates a new DIV that is used as a toolbar and adds
				// toolbar buttons.
				let spacer = document.createElement('div');
				spacer.style.display = 'inline';
				spacer.style.padding = '8px';

				// Defines a new export action
				editor.addAction('save', function (editor, cell) {
					$scope.saveSchema($scope.graph);
				});
				// Defines a new export action
				editor.addAction('properties', function (editor, cell) {
					if (!cell) {
						cell = $scope.graph.getSelectionCell();
					}
					if ($scope.graph.isHtmlLabel(cell)) {
						if (cell) {
							// assume column
							if (cell.value.isSQL) {
								// assume View's (the only) column
								messageHub.showFormDialog(
									"dsmColumnSQLProperties",
									"Column SQL properties",
									[{
										id: `dsmt-${cell.id}`,
										type: "input",
										submitOnEnterId: "b1",
										label: "SQL",
										value: cell.value.name,
									}],
									[{
										id: "b1",
										type: "emphasized",
										label: "Update",
										whenValid: true,
									},
									{
										id: "b2",
										type: "transparent",
										label: "Cancel",
									}],
									"dsmEditor.column.sqlproperties",
									"Updating..."
								);
							} else {
								// assume Table's column
								messageHub.showFormDialog(
									"dsmColumnProperties",
									"Column properties",
									[{
										id: `dsmt-${cell.id}`,
										type: "input",
										label: "SQL",
										value: cell.value.name,
									}, {
										id: "dsmdType",
										type: "dropdown",
										label: "Data type",
										required: true,
										value: cell.value.type,
										items: $scope.dataTypes,
									}, {
										id: 'dsmcpLength',
										type: "input",
										label: "Length",
										placeholder: '20',
										inputRules: {
											patterns: ['^[0-9]*$'],
										},
										value: cell.value.columnLength,
									}, {
										id: "dsmcpPrimaryKey",
										type: "checkbox",
										label: "Primary Key",
										value: $scope.getBoolean(cell.value.primaryKey),
									}, {
										id: "dsmcpAutoIncrement",
										type: "checkbox",
										label: "Auto increment",
										value: $scope.getBoolean(cell.value.autoIncrement),
									}, {
										id: "dsmcpNotNull",
										type: "checkbox",
										label: "Not null",
										value: $scope.getBoolean(cell.value.notNull),
									}, {
										id: "dsmcpunique",
										type: "checkbox",
										label: "Unique",
										value: $scope.getBoolean(cell.value.unique),
									}, {
										id: "dsmcpPrecision",
										type: "input",
										label: "Precision",
										placeholder: "Enter precision number",
										value: cell.value.precision,
										inputRules: {
											patterns: ['^[0-9]*$'],
										},
									}, {
										id: "dsmcpScale",
										type: "input",
										label: "Scale",
										placeholder: "Enter scale number",
										value: cell.value.scale,
										inputRules: {
											patterns: ['^[0-9]*$'],
										},
									}, {
										id: "dsmcpDefaultValue",
										type: "input",
										label: "Default Value",
										placeholder: "Enter value",
										value: cell.value.defaultValue,
									}],
									[{
										id: "b1",
										type: "emphasized",
										label: "Update",
										whenValid: true,
									},
									{
										id: "b2",
										type: "transparent",
										label: "Cancel",
									}],
									"dsmEditor.column.properties",
									"Updating..."
								);
							}
						} else {
							messageHub.showAlertWarning(
								"Nothing is selected",
								"Please select a table, view or column."
							);
						}
					} else {
						// assume Table, View or Connector
						if (cell.value) {
							// assume Table or View
							messageHub.showFormDialog(
								"dsmTableProperties",
								(cell.value.type === "TABLE") ? "Table properties" : "View properties",
								[{
									id: `dsmt-${cell.id}`,
									type: "input",
									submitOnEnterId: "b1",
									label: "Name",
									value: cell.value.name,
								}],
								[{
									id: "b1",
									type: "emphasized",
									label: "Update",
									whenValid: true,
								},
								{
									id: "b2",
									type: "transparent",
									label: "Cancel",
								}],
								"dsmEditor.table.properties",
								"Updating..."
							);
						}
						// else {
						// 	// assume connector
						// 	// TODO
						// }

					}
				});

				// Defines a new move up action
				editor.addAction('moveup', function (editor, cell) {
					if (cell.parent.children.length > 1) {
						$scope.graph.getModel().beginUpdate();
						try {
							for (index = 0; index < cell.parent.children.length; index++) {
								let current = cell.parent.children[index];
								if (cell.id === current.id) {
									if (index > 0) {
										let previous = cell.parent.children[index - 1];
										let y = previous.geometry.y;
										previous.geometry.y = current.geometry.y;
										current.geometry.y = y;
										cell.parent.children[index - 1] = current;
										cell.parent.children[index] = previous;
										break;
									}

								}
							}
						} finally {
							$scope.graph.getModel().endUpdate();
							$scope.graph.refresh();
						}
					}
				});

				// Defines a new move down action
				editor.addAction('movedown', function (editor, cell) {
					if (cell.parent.children.length > 2) {
						$scope.graph.getModel().beginUpdate();
						try {
							for (index = 0; index < cell.parent.children.length; index++) {
								let current = cell.parent.children[index];
								if (cell.id === current.id) {
									if (index < cell.parent.children.length - 1) {
										let next = cell.parent.children[index + 1];
										let y = next.geometry.y;
										next.geometry.y = current.geometry.y;
										current.geometry.y = y;
										cell.parent.children[index + 1] = current;
										cell.parent.children[index] = next;
										break;
									}
								}
							}
						} finally {
							$scope.graph.getModel().endUpdate();
							$scope.graph.refresh();
						}
					}
				});
				// Defines a new save action
				editor.addAction('copy', function (editor, cell) {
					mxClipboard.copy($scope.graph);
				});
				// Defines a new save action
				editor.addAction('paste', function (editor, cell) {
					mxClipboard.paste($scope.graph);
				});

				// Defines a create SQL action
				editor.addAction('showSql', function (editor, cell) {
					let sql = createSql($scope.graph);
					if (sql.length > 0) {
						messageHub.showFormDialog(
							"dsmSchemaSQL",
							"Schema SQL",
							[{
								id: "dsmssta",
								type: "textarea",
								label: "SQL",
								rows: 20,
								value: sql.trim(),
							}],
							[{
								id: "b1",
								type: "emphasized",
								label: "Close",
							}],
							"dsmEditor.schema.sql",
							"Closing..."
						);
					} else {
						messageHub.showAlertInfo(
							"Warning",
							'Schema is empty'
						);
					}
				});

				$scope.save = function () {
					editor.execute('save');
				};
				$scope.properties = function () {
					editor.execute('properties');
				};
				$scope.copy = function () {
					editor.execute('copy');
				};
				$scope.paste = function () {
					editor.execute('paste');
				};
				$scope.undo = function () {
					editor.execute('undo');
				};
				$scope.redo = function () {
					editor.execute('redo');
				};
				$scope.delete = function () {
					editor.execute('delete');
				};
				$scope.show = function () {
					editor.execute('show');
				};
				$scope.print = function () {
					editor.execute('print');
				};
				$scope.showSql = function () {
					editor.execute('showSql');
				};
				// // Defines export XML action
				// editor.addAction('export', function (editor, cell) {
				// 	let textarea = document.createElement('textarea');
				// 	textarea.style.width = '410px';
				// 	textarea.style.height = '420px';
				// 	let enc = new mxCodec(mxUtils.createXmlDocument());
				// 	let node = enc.encode(editor.graph.getModel());
				// 	textarea.value = mxUtils.getPrettyXml(node);
				// 	showModalWindow('XML', textarea, 410, 440);
				// });
				// $scope.export = function () {
				// 	editor.execute('export');
				// };

				$scope.collapseAll = function () {
					editor.execute('collapseAll');
				};
				$scope.expandAll = function () {
					editor.execute('expandAll');
				};
				$scope.zoomIn = function () {
					editor.execute('zoomIn');
				};
				$scope.zoomOut = function () {
					editor.execute('zoomOut');
				};
				$scope.actualSize = function () {
					editor.execute('actualSize');
				};
				$scope.fit = function () {
					editor.execute('fit');
				};

				// Creates the outline (navigator, overview) for moving
				// around the graph in the top, right corner of the window.
				new mxOutline($scope.graph, outline);
			}

			let doc = mxUtils.parseXml(contents);
			let codec = new mxCodec(doc.mxGraphModel);
			codec.decode(doc.documentElement.getElementsByTagName('mxGraphModel')[0], $scope.graph.getModel());
			$scope.graph.model.addListener(mxEvent.START_EDIT, function (_sender, _evt) {
				messageHub.setEditorDirty($scope.dataParameters.file, true);
			});
		};

		$scope.dataParameters = ViewParameters.get();
		if (!$scope.dataParameters.hasOwnProperty('file')) {
			$scope.state.error = true;
			$scope.errorMessage = "The 'file' data parameter is missing.";
		} else if (!$scope.dataParameters.hasOwnProperty('contentType')) {
			$scope.state.error = true;
			$scope.errorMessage = "The 'contentType' data parameter is missing.";
		} else {
			schemaFile = $scope.dataParameters.file.substring(0, $scope.dataParameters.file.lastIndexOf('.')) + '.schema';
			$scope.load();
		}
	});




© 2015 - 2025 Weber Informatics LLC | Privacy Policy