release version 1.10.0
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyCopyToClipboardButton', {
|
||||
bindings: {
|
||||
title: '@',
|
||||
textToCopy: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<button type="button" class="btn-clipboard" data-toggle="tooltip" title="{{$ctrl.title}}"
|
||||
ng-click="$ctrl.copyLocationToClipboard($ctrl.textToCopy)">
|
||||
<span class="fa fa-copy"></span>
|
||||
</button>
|
||||
`,
|
||||
controller: entaxyCopyToClipboardButtonController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCopyToClipboardButtonController($timeout) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.copyLocationToClipboard = function(textToCopy) {
|
||||
let clipboard = new ClipboardJS('.btn-clipboard', {
|
||||
text: (trigger) => textToCopy
|
||||
});
|
||||
setTimeout(() => clipboard.destroy(), 1000);
|
||||
}
|
||||
}
|
||||
entaxyCopyToClipboardButtonController.$inject = ['$timeout'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,158 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function(Entaxy) {
|
||||
'use strict';
|
||||
|
||||
Entaxy._module.factory('ContextMenuService', function() {
|
||||
return {
|
||||
element: null,
|
||||
menuElement: null
|
||||
};
|
||||
}).directive('contextMenu', ['$document', 'ContextMenuService', function($document, ContextMenuService) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
'item': '=',
|
||||
'contextMenuOptions': '='
|
||||
},
|
||||
link: function($scope, $element, $attrs) {
|
||||
|
||||
function createMenuElement() {
|
||||
let contextMenuOptions = $scope.contextMenuOptions;
|
||||
if (contextMenuOptions && contextMenuOptions.length > 0) {
|
||||
let menuElementContainer = document.createElement("div");
|
||||
menuElementContainer.id = "context-menu";
|
||||
menuElementContainer.className = "dropdown";
|
||||
menuElementContainer.style.position = "fixed";
|
||||
let menuElement = menuElementContainer.appendChild(document.createElement("ul"));
|
||||
menuElement.className = "dropdown-menu";
|
||||
contextMenuOptions.forEach(option => {
|
||||
let optionElement = menuElement.appendChild(document.createElement("li"));
|
||||
if (option.divider) {
|
||||
optionElement.className = 'divider';
|
||||
} else {
|
||||
let optionRefElement = optionElement.appendChild(document.createElement("a"));
|
||||
optionRefElement.appendChild(document.createTextNode(option.name));
|
||||
optionRefElement.onclick = (event) => handleAction(event, option.actionFn);
|
||||
}
|
||||
});
|
||||
return menuElementContainer;
|
||||
}
|
||||
}
|
||||
|
||||
function handleAction(event, actionFn) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (event.button === 0) {
|
||||
if (actionFn) {
|
||||
actionFn($scope.item);
|
||||
}
|
||||
}
|
||||
handleClickEvent(event);
|
||||
}
|
||||
|
||||
let opened = false;
|
||||
|
||||
function open(event, menuElement) {
|
||||
menuElement.addClass('open');
|
||||
|
||||
let viewportHeight =
|
||||
Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
|
||||
let viewportWidth =
|
||||
Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
||||
let elementHeight = menuElement[0].scrollHeight;
|
||||
let elementWidth = menuElement[0].scrollWidth;
|
||||
let top = event.clientY;
|
||||
let left = event.clientX;
|
||||
|
||||
if (top > (viewportHeight - elementHeight)) {
|
||||
top -= elementHeight;
|
||||
}
|
||||
if (left > (viewportWidth - elementWidth)) {
|
||||
left -= elementWidth;
|
||||
}
|
||||
|
||||
menuElement.css('top', top + 'px');
|
||||
menuElement.css('left', left + 'px');
|
||||
opened = true;
|
||||
}
|
||||
|
||||
function close(menuElement) {
|
||||
menuElement.removeClass('open');
|
||||
menuElement.remove();
|
||||
opened = false;
|
||||
}
|
||||
|
||||
$element.bind('contextmenu', function(event) {
|
||||
if (ContextMenuService.menuElement !== null) {
|
||||
close(ContextMenuService.menuElement);
|
||||
}
|
||||
$element[0].appendChild(createMenuElement());
|
||||
ContextMenuService.menuElement = angular.element(
|
||||
document.getElementById("context-menu")
|
||||
);
|
||||
ContextMenuService.element = event.target;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$scope.$apply(function() {
|
||||
open(event, ContextMenuService.menuElement);
|
||||
});
|
||||
});
|
||||
|
||||
function handleKeyUpEvent(event) {
|
||||
if (opened && event.keyCode === 27) {
|
||||
$scope.$apply(function() {
|
||||
close(ContextMenuService.menuElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickEvent(event) {
|
||||
if (opened && (event.button !== 2 || event.target !== ContextMenuService.element)) {
|
||||
$scope.$apply(function() {
|
||||
close(ContextMenuService.menuElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$document.bind('keyup', handleKeyUpEvent);
|
||||
// Firefox treats a right-click as a click and a contextmenu event
|
||||
// while other browsers just treat it as a contextmenu event
|
||||
$document.bind('click', handleClickEvent);
|
||||
$document.bind('contextmenu', handleClickEvent);
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
$document.unbind('keyup', handleKeyUpEvent);
|
||||
$document.unbind('click', handleClickEvent);
|
||||
$document.unbind('contextmenu', handleClickEvent);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]).name;
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.directive('draggable', function() {
|
||||
return function(scope, element) {
|
||||
let el = element[0];
|
||||
|
||||
el.draggable = true;
|
||||
|
||||
el.addEventListener(
|
||||
'dragstart',
|
||||
function(e) {
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData("text/html", e.target.id);
|
||||
this.classList.add('drag');
|
||||
return false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
el.addEventListener(
|
||||
'dragend',
|
||||
function(e) {
|
||||
this.classList.remove('drag');
|
||||
return false;
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
})
|
||||
.directive('droppable', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
element[0].addEventListener('drop', scope.handleDrop, false);
|
||||
element[0].addEventListener('dragover', scope.handleDragOver, false);
|
||||
scope.handleDropFn = $parse(attrs.handleDropFn);
|
||||
},
|
||||
controller: ['$scope', function($scope) {
|
||||
$scope.handleDrop = function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if ($scope.handleDropFn) {
|
||||
let droppedElementId = e.dataTransfer.getData("text/html");
|
||||
$scope.droppedElementId = droppedElementId;
|
||||
$scope.handleDropFn($scope);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.handleDragOver = function (e) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
};
|
||||
}]
|
||||
};
|
||||
}])
|
||||
.name;
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,54 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.directive('modalDialog', function(){
|
||||
return {
|
||||
restrict: 'AC',
|
||||
link: function($scope, element) {
|
||||
var draggableStr = "draggableModal";
|
||||
var header = $(".modal-header", element);
|
||||
|
||||
header.on('mousedown', (mouseDownEvent) => {
|
||||
var modalDialog = element;
|
||||
var offset = header.offset();
|
||||
|
||||
modalDialog.addClass(draggableStr).parents().on('mousemove', (mouseMoveEvent) => {
|
||||
$("." + draggableStr, modalDialog.parents()).offset({
|
||||
top: mouseMoveEvent.pageY - (mouseDownEvent.pageY - offset.top),
|
||||
left: mouseMoveEvent.pageX - (mouseDownEvent.pageX - offset.left)
|
||||
});
|
||||
}).on('mouseup', () => {
|
||||
modalDialog.removeClass(draggableStr);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.name;
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,109 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.directive('entaxyFileDrop', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
require: 'ngModel',
|
||||
link: function (scope, element, attrs, ngModel) {
|
||||
|
||||
let enterTarget = null;
|
||||
|
||||
element.on('dragenter', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
enterTarget = e.target;
|
||||
element.addClass('highlighted');
|
||||
createNotification();
|
||||
});
|
||||
|
||||
element.on('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
element.on('dragleave', function (e) {
|
||||
if (e.target === enterTarget) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
element.removeClass('highlighted');
|
||||
removeNotification();
|
||||
}
|
||||
});
|
||||
|
||||
let notificationContainer = null;
|
||||
|
||||
function createNotification() {
|
||||
if (notificationContainer === null) {
|
||||
notificationContainer = document.createElement('div');
|
||||
notificationContainer.className = 'upload-notification';
|
||||
let span = document.createElement('span');
|
||||
span.className = 'fa fa-upload';
|
||||
notificationContainer.appendChild(span);
|
||||
notificationContainer.appendChild(document.createTextNode('Drop file to upload'));
|
||||
|
||||
let elementWidth = element.width();
|
||||
let offset = 150 + elementWidth/2 + 20;
|
||||
notificationContainer.style.left = 'calc(100vw - ' + offset + 'px)';
|
||||
|
||||
element.append(notificationContainer);
|
||||
}
|
||||
}
|
||||
|
||||
function removeNotification() {
|
||||
if (notificationContainer !== null) {
|
||||
notificationContainer.parentNode.removeChild(notificationContainer);
|
||||
notificationContainer = null;
|
||||
}
|
||||
}
|
||||
|
||||
element.on('drop', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
element.removeClass('highlighted');
|
||||
removeNotification();
|
||||
|
||||
if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length > 0) {
|
||||
ngModel.$setViewValue(e.originalEvent.dataTransfer.files[0]);
|
||||
|
||||
let processFn = $parse(attrs.processFn);
|
||||
if (processFn) {
|
||||
processFn(scope);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
}])
|
||||
.name;
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.directive("setFileModel", function() {
|
||||
return {
|
||||
require: "ngModel",
|
||||
link: function postLink(scope, element, attrs, ngModel) {
|
||||
element.on("click", function (e) {
|
||||
element[0].value = null;
|
||||
})
|
||||
|
||||
element.on("change", function(e) {
|
||||
if (element[0].files[0]) {
|
||||
ngModel.$setViewValue(element[0].files[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
.name;
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,201 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyExpandableList', {
|
||||
bindings: {
|
||||
items: '<',
|
||||
itemsLabel: '@',
|
||||
itemsLabelPlural: '@',
|
||||
filter: '<',
|
||||
actionButtons: '<',
|
||||
enableButtonForItemFn: '<',
|
||||
useToolbar: '<',
|
||||
toolbarActionButtons: '<',
|
||||
enableToolbarActionButtons: '<',
|
||||
showSelectBox: '<',
|
||||
onCheckBoxChangeFn: '<',
|
||||
emptyStateConfig: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="expandable-list-toolbar-container" ng-if="$ctrl.useToolbar">
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
</div>
|
||||
<div class="expandable-list-container">
|
||||
<pf-list-view class="entaxy-list" items="$ctrl.viewedItems" config="$ctrl.listConfig"
|
||||
action-buttons="$ctrl.actionButtons" empty-state-config="$ctrl.emptyStateConfig">
|
||||
<div class="list-view-pf-left ng-if="item.typeIcon">
|
||||
<span class="{{item.typeIcon}} list-view-pf-icon-sm"></span>
|
||||
</div>
|
||||
<div class="list-view-pf-description">
|
||||
<div class="list-group-item-heading">
|
||||
{{item.displayName}}
|
||||
</div>
|
||||
<div class="list-group-item-text" ng-if="item.text">
|
||||
{{item.text}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-view-pf-additional-info" ng-if="item.additionalInfo">
|
||||
<div class="list-view-pf-additional-info-item">
|
||||
{{item.additionalInfo}}
|
||||
</div>
|
||||
</div>
|
||||
<list-expanded-content>
|
||||
<div class="nested-list">
|
||||
<pf-list-view class="entaxy-list" items="$parent.item.viewedSublistItems"
|
||||
config="$ctrl.sublistConfig">
|
||||
<div class="list-view-pf-left" ng-if="item.typeIcon">
|
||||
<span class="{{item.typeIcon}} list-view-pf-icon-sm"></span>
|
||||
</div>
|
||||
<div class="list-view-pf-description">
|
||||
<div class="list-group-item-heading">
|
||||
{{item.displayName}}
|
||||
</div>
|
||||
<div class="list-group-item-text" ng-if="item.text">
|
||||
{{item.text}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-view-pf-additional-info" ng-if="item.additionalInfo">
|
||||
<div class="list-view-pf-additional-info-item">
|
||||
{{item.additionalInfo}}
|
||||
</div>
|
||||
</div>
|
||||
</pf-list-view>
|
||||
</div>
|
||||
</list-expanded-content>
|
||||
</pf-list-view>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyExpandableListController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyExpandableListController($scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
if (ctrl.useToolbar) {
|
||||
ctrl.toolbarConfig.filterConfig.itemsLabel = ctrl.itemsLabel ? ctrl.itemsLabel : 'Result';
|
||||
ctrl.toolbarConfig.filterConfig.itemsLabelPlural = ctrl.itemsLabelPlural ? ctrl.itemsLabelPlural : 'Results';
|
||||
ctrl.toolbarConfig.actionsConfig = {primaryActions: ctrl.toolbarActionButtons};
|
||||
|
||||
$scope.$watch('$ctrl.enableToolbarActionButtons', function (newValue) {
|
||||
ctrl.toolbarConfig.actionsConfig.primaryActions.forEach(actionButton => {
|
||||
actionButton.isDisabled = !newValue;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.listConfig = {
|
||||
selectionMatchProp: 'name',
|
||||
selectItems: false,
|
||||
showSelectBox: false,
|
||||
useExpandingRows: true
|
||||
}
|
||||
|
||||
let subListConfig = Entaxy.deepCopy(ctrl.listConfig);
|
||||
if (ctrl.showSelectBox) {
|
||||
subListConfig.showSelectBox = ctrl.showSelectBox;
|
||||
subListConfig.onCheckBoxChange = ctrl.onCheckBoxChangeFn;
|
||||
}
|
||||
ctrl.sublistConfig = subListConfig;
|
||||
}
|
||||
|
||||
$scope.$watchCollection('$ctrl.items', function (newValue) {
|
||||
if (newValue && newValue.length > 0) {
|
||||
ctrl.viewedItems = ctrl.items;
|
||||
ctrl.viewedItems.forEach(item => {
|
||||
if (item.sublist) {
|
||||
item.viewedSublistItems = item.sublist;
|
||||
}
|
||||
});
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
ctrl.listConfig.itemsAvailable = true;
|
||||
} else {
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = 0;
|
||||
ctrl.listConfig.itemsAvailable = false;
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Search...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
actionsConfig: {},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
function filterChange(filters) {
|
||||
applyFilters(filters);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function applyFilters(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter, returnSublistsToOriginalState);
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
if (ctrl.filter) {
|
||||
return ctrl.filter(item, filter);
|
||||
} else {
|
||||
let match = true;
|
||||
if (filter.id === 'displayName') {
|
||||
match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
if (!match && item.sublist && item.sublist.length > 0) {
|
||||
let viewedSublistItems = Entaxy.applyFilters(item.sublist, [ filter ], matchesFilter);
|
||||
item.viewedSublistItems = viewedSublistItems;
|
||||
match = viewedSublistItems.length > 0;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
function returnSublistsToOriginalState(items) {
|
||||
items.forEach(item => {
|
||||
if (item.sublist) {
|
||||
item.viewedSublistItems = item.sublist;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyExpandableListController.$inject = ['$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,163 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyExtendedData', {
|
||||
template:
|
||||
`
|
||||
<div id="entaxy-extended-data" class="entaxy-extended-data" ng-if="$ctrl.messages">
|
||||
<uib-accordion>
|
||||
<div uib-accordion-group is-open="$ctrl.isOpen">
|
||||
<div uib-accordion-heading>
|
||||
<div class="entaxy-extended-data-short-message {{message.type}}" ng-repeat="message in $ctrl.messages">
|
||||
{{message.short}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="entaxy-extended-data-messages-container">
|
||||
<uib-accordion>
|
||||
<div uib-accordion-group class="entaxy-extended-data-message-container {{message.type}}"
|
||||
ng-class="{'disabled': !message.extraInfo}"
|
||||
is-open="message.open" is-disabled="!message.extraInfo"
|
||||
ng-repeat="message in $ctrl.messages">
|
||||
<div uib-accordion-heading>
|
||||
<span class="pficon"
|
||||
ng-class="{'pficon-edit': !message.type, 'pficon-warning-triangle-o': message.type}"></span>
|
||||
<span class="entaxy-extended-data-message">{{message.full}}</span>
|
||||
</div>
|
||||
<div class="entaxy-extended-data-message-extra-info-container">
|
||||
<pre>{{message.extraInfo}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</uib-accordion>
|
||||
</div>
|
||||
</div>
|
||||
</uib-accordion>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyExtendedDataController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyExtendedDataController(workspace, $scope, $q, entaxyService, entaxyAttributesCacheService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
readExtendedData();
|
||||
|
||||
$scope.$on('jmxTreeClicked', function () {
|
||||
readExtendedData();
|
||||
});
|
||||
}
|
||||
|
||||
function readExtendedData() {
|
||||
ctrl.messages = undefined;
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
let attributes;
|
||||
if (selectedMbeanName) {
|
||||
entaxyAttributesCacheService.setToUpdate(selectedMbeanName);
|
||||
attributes = entaxyAttributesCacheService.getAttributes(selectedMbeanName);
|
||||
}
|
||||
|
||||
if (attributes && attributes.RuntimeType && attributes.RuntimeType !== Entaxy.RUNTIME_TYPE.ROUTE_CONTAINER) {
|
||||
let messages = [];
|
||||
let promises = [];
|
||||
|
||||
if (attributes.BundleState) {
|
||||
let status = attributes.BundleState;
|
||||
if (status === 'Failure') {
|
||||
promises.push(entaxyService.getBundleDiag(attributes.BundleId).then(result =>
|
||||
messages.push(getStatusMessage(status, result))));
|
||||
} else {
|
||||
messages.push(getStatusMessage(status));
|
||||
}
|
||||
}
|
||||
|
||||
promises.push(entaxyService.readExtendedData(selectedMbeanName)
|
||||
.then(result => {
|
||||
let extendedData = JSON.parse(result);
|
||||
|
||||
if (extendedData.cluster) {
|
||||
messages.push(getClusterMessage(extendedData.cluster));
|
||||
}
|
||||
|
||||
if (extendedData.applications) {
|
||||
messages.push(getApplicationsMessage(extendedData.applications.application));
|
||||
}
|
||||
}));
|
||||
|
||||
$q.all(promises).then(() => {
|
||||
ctrl.messages = messages;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusMessage(status, extraInfo) {
|
||||
return {
|
||||
short: status.toLowerCase(),
|
||||
full: 'Status: ' + status,
|
||||
extraInfo: extraInfo,
|
||||
type: status === 'Failure' ? 'error' : undefined
|
||||
};
|
||||
}
|
||||
|
||||
function getClusterMessage(cluster) {
|
||||
let message = {
|
||||
short: cluster.objectClusterState,
|
||||
full: 'Cluster: ',
|
||||
type: cluster.objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED ? 'warning' : undefined
|
||||
};
|
||||
if (cluster.groups && cluster.groups.length > 0) {
|
||||
message.full += cluster.groups.join(', ');
|
||||
} else {
|
||||
message.full += message.short;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function getApplicationsMessage(applications) {
|
||||
let message = {
|
||||
short: 'managed',
|
||||
full: 'Object is installed as a part of the '
|
||||
};
|
||||
message.full += applications.length > 1 ? 'applications: ' : 'application: ';
|
||||
let lastApplicationIndex = applications.length - 1;
|
||||
for (let i = 0; i < lastApplicationIndex; i++) {
|
||||
message.full += getApplicationFullName(applications[i]) + ', ';
|
||||
}
|
||||
message.full += getApplicationFullName(applications[lastApplicationIndex]);
|
||||
return message;
|
||||
}
|
||||
|
||||
function getApplicationFullName(application) {
|
||||
return application.name + ':' + application.version + '/' + application.revision;
|
||||
}
|
||||
}
|
||||
entaxyExtendedDataController.$inject = ['workspace', '$scope', '$q', 'entaxyService', 'entaxyAttributesCacheService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,61 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyFormFieldExtraInfo', {
|
||||
bindings: {
|
||||
type: '<',
|
||||
message: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-field-extra-info-container {{$ctrl.type}}">
|
||||
<span class="{{$ctrl.iconClass}}"></span>
|
||||
<span class="entaxy-field-extra-info-message">{{$ctrl.message}}</span>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyFormFieldExtraInfoController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyFormFieldExtraInfoController() {
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
ctrl.iconClass = getIconClassByType();
|
||||
}
|
||||
|
||||
function getIconClassByType() {
|
||||
switch (ctrl.type) {
|
||||
case Entaxy.NOTIFICATION_TYPE.INFO:
|
||||
default:
|
||||
return 'pficon pficon-info';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,187 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyFormFields', {
|
||||
bindings: {
|
||||
items: '<',
|
||||
errors: '<',
|
||||
mode: '<',
|
||||
formController: '<',
|
||||
updateFieldsAfterSelectionChangeFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': $ctrl.errors[formField.name] && formField.type !== 'list'}"
|
||||
ng-repeat="formField in $ctrl.items" ng-if="!formField.isBackRef && !formField.isHidden">
|
||||
<entaxy-form-field-extra-info class="col-sm-12"
|
||||
type="formField.ui.fieldExtraInfo.type" message="formField.ui.fieldExtraInfo.message"
|
||||
ng-if="formField.ui && formField.ui.fieldExtraInfo && formField.ui.fieldExtraInfo.displayOnMode === $ctrl.mode">
|
||||
</entaxy-form-field-extra-info>
|
||||
<div class="col-sm-4 label-col" ng-if="!formField.excludeLabel">
|
||||
<label class="control-label" ng-class="{'required-pf': formField.required}" for="{{formField.name}}">
|
||||
{{formField.label}}
|
||||
</label>
|
||||
<button type="button" class="btn btn-link label-description-popover"
|
||||
popover-placement="auto top-left" popover-trigger="'outsideClick'"
|
||||
uib-popover-html="formField.description" ng-if="formField.description">
|
||||
<span class="pficon pficon-help"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div ng-class="{'col-sm-7': !formField.excludeLabel, 'col-sm-12': formField.excludeLabel}">
|
||||
<input type="{{formField.type}}" id="{{formField.name}}" placeholder="{{formField.placeholder}}"
|
||||
ng-class="{'form-control': formField.type !== 'checkbox'}" ng-model="formField.value"
|
||||
ng-readonly="formField.readOnly" ng-disabled="formField.type === 'checkbox' && formField.readOnly"
|
||||
ng-if="$ctrl.isSimpleInput(formField)">
|
||||
<textarea id="{{formField.name}}" class="form-control" ng-model="formField.value"
|
||||
ng-readonly="formField.readOnly" ng-if="$ctrl.isTextarea(formField)"></textarea>
|
||||
<entaxy-password-input id="{{formField.name}}" name="formField.name" model="formField.value"
|
||||
confirmation-model="formField.confirmationValue" readonly="formField.readOnly"
|
||||
ignore-confirmation-value="formField.ignoreConfirmationValue" errors="$ctrl.errors"
|
||||
ng-if="$ctrl.isPassword(formField)"></entaxy-password-input>
|
||||
<entaxy-url-input id="{{formField.name}}" model="formField.value" config="formField.typeInfo"
|
||||
readonly="formField.readOnly" ng-if="$ctrl.isUrl(formField)"
|
||||
form-controller="$ctrl.formController"></entaxy-url-input>
|
||||
<entaxy-select type="formField.type" id="{{formField.name}}" filter="formField.filter"
|
||||
model="formField.value" options="formField.options" readonly="formField.readOnly"
|
||||
update-parent-fn="$ctrl.updateFieldsAfterSelectionChangeFn"
|
||||
update-parent="formField.typeInfo ? formField.typeInfo.updateParentFields : false"
|
||||
creation-enabled="formField.typeInfo && formField.typeInfo.enablePrivateObjectCreation"
|
||||
is-empty-included="formField.typeInfo ? formField.typeInfo.isEmptyIncluded : false"
|
||||
ng-if="$ctrl.isEntaxySelect(formField)" form-controller="$ctrl.formController"></entaxy-select>
|
||||
<entaxy-select-from-enum id="{{formField.name}}" values="formField.typeInfo.values"
|
||||
model="formField.value" readonly="formField.readOnly" multiple="formField.typeInfo.multiple"
|
||||
is-empty-included="formField.typeInfo.isEmptyIncluded"
|
||||
empty-option-name="formField.typeInfo.emptyOptionName"
|
||||
ng-if="$ctrl.isSelectFromEnum(formField)"></entaxy-select-from-enum>
|
||||
<entaxy-xml id="{{formField.name}}" ng-model="formField.value" mode="$ctrl.localMode"
|
||||
ng-if="$ctrl.isXml(formField)" readonly="formField.readOnly"
|
||||
form-controller="$ctrl.formController"></entaxy-xml>
|
||||
<entaxy-list-input id="{{formField.name}}" items="formField.value" ng-if="$ctrl.isList(formField)"
|
||||
creation-enabled="formField.typeInfo && formField.typeInfo.enablePrivateObjectCreation"
|
||||
creation-types="formField.typeInfo ? formField.typeInfo.privateObjectTypes : undefined"
|
||||
item-factory-filter="formField.itemFactoryFilter" mode="$ctrl.mode"
|
||||
readonly="formField.readOnly" validation="formField.validation"
|
||||
item-title-template="formField.typeInfo ? formField.typeInfo.itemTitle : undefined"
|
||||
errors="$ctrl.errors[formField.name]" form-controller="$ctrl.formController"></entaxy-list-input>
|
||||
<entaxy-resource-input id="{{formField.name}}" name="{{formField.name}}" model="formField.value"
|
||||
ng-if="$ctrl.isResourceInput(formField)"></entaxy-resource-input>
|
||||
<entaxy-inner-object-input id="{{formField.name}}" readonly="formField.readOnly"
|
||||
model="formField.value" mode="$ctrl.mode" type="formField.type" form-controller="$ctrl.formController"
|
||||
object-factory-filter="formField.objectFactoryFilter" field-name="formField.label"
|
||||
ng-if="$ctrl.isInnerObjectInput(formField)"></entaxy-inner-object-input>
|
||||
<entaxy-map-input id="{{formField.name}}" model="formField.value" items="formField.mapItems"
|
||||
duplicate-keys="formField.duplicateKeys" has-errors="formField.hasErrors" readonly="formField.readOnly"
|
||||
ng-if="$ctrl.isMapInput(formField)" form-controller="$ctrl.formController"></entaxy-map-input>
|
||||
<span class="help-block" ng-show="$ctrl.errors[formField.name] && formField.type !== 'list'">
|
||||
{{$ctrl.errors[formField.name]}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyFormFieldsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyFormFieldsController($scope) {
|
||||
'ngInject';
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.localMode = ctrl.mode === Entaxy.MODAL_MODES.ADD ? Entaxy.MODAL_MODES.EDIT : ctrl.mode;
|
||||
}
|
||||
|
||||
const TYPES = {
|
||||
PASSWORD: 'password',
|
||||
ENUM: 'enum',
|
||||
LIST: 'list',
|
||||
URL: 'url',
|
||||
XML_ROUTE: 'xml:route',
|
||||
RESOURCE: 'resource',
|
||||
MAP: 'map'
|
||||
};
|
||||
|
||||
ctrl.isSimpleInput = function (formField) {
|
||||
return !isRuntimeTyped(formField.type)
|
||||
&& formField.type !== TYPES.PASSWORD
|
||||
&& formField.type !== TYPES.LIST
|
||||
&& formField.type !== TYPES.XML_ROUTE
|
||||
&& formField.type !== TYPES.RESOURCE
|
||||
&& formField.type !== TYPES.MAP
|
||||
&& (!formField.typeInfo || (formField.typeInfo && formField.typeInfo.type === 'String'))
|
||||
&& !formField.useTextarea;
|
||||
}
|
||||
|
||||
ctrl.isTextarea = function (formField) {
|
||||
return formField.type === 'text' && formField.useTextarea;
|
||||
}
|
||||
|
||||
ctrl.isPassword = function (formField) {
|
||||
return formField.type === TYPES.PASSWORD;
|
||||
}
|
||||
|
||||
ctrl.isUrl = function (formField) {
|
||||
return formField.type === TYPES.URL && formField.typeInfo;
|
||||
}
|
||||
|
||||
ctrl.isEntaxySelect = function (formField) {
|
||||
return isRuntimeTyped(formField.type) && !formField.innerObject;
|
||||
}
|
||||
|
||||
ctrl.isInnerObjectInput = function (formField) {
|
||||
return isRuntimeTyped(formField.type) && formField.innerObject;
|
||||
}
|
||||
|
||||
ctrl.isSelectFromEnum = function (formField) {
|
||||
return formField.typeInfo
|
||||
&& (formField.typeInfo.type === TYPES.ENUM || formField.typeInfo.type === TYPES.LIST)
|
||||
&& (formField.typeInfo.values || (!formField.typeInfo.values && formField.readOnly));
|
||||
}
|
||||
|
||||
ctrl.isXml = function (formField) {
|
||||
return formField.type === TYPES.XML_ROUTE;
|
||||
}
|
||||
|
||||
ctrl.isList = function (formField) {
|
||||
return formField.type === TYPES.LIST;
|
||||
}
|
||||
|
||||
ctrl.isResourceInput = function (formField) {
|
||||
return formField.type === TYPES.RESOURCE;
|
||||
}
|
||||
|
||||
ctrl.isMapInput = function (formField) {
|
||||
return formField.type === TYPES.MAP;
|
||||
}
|
||||
|
||||
function isRuntimeTyped(formFieldType) {
|
||||
return formFieldType.startsWith(Entaxy.RUNTIME_TYPE_PREFIX) ||
|
||||
formFieldType.startsWith(Entaxy.RUNTIME_TYPE_SECURITY_PREFIX);
|
||||
}
|
||||
}
|
||||
entaxyFormFieldsController.$inject = ['$scope'];
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,107 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyHeader', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-header">
|
||||
<header>
|
||||
<h1 id="entaxy-header-title" ng-class="{'changed': $ctrl.isChanged}">{{$ctrl.title}}</h1>
|
||||
<button type="button" class="btn btn-link label-description-popover"
|
||||
popover-placement="{{$ctrl.popoverPlacement}}" popover-trigger="'outsideClick'"
|
||||
popover-class="entaxy-header-popover" popover-is-open="$ctrl.isPopoverOpen"
|
||||
uib-popover="{{$ctrl.objectName}}" ng-if="$ctrl.objectName">
|
||||
<span class="pficon pficon-info"></span>
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyHeaderController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyHeaderController(workspace, $scope, entaxyPrivateObjectsCacheService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
populateData(selectedMbean);
|
||||
|
||||
$scope.$on('jmxTreeClicked', function (event, selectedNode) {
|
||||
populateData(selectedNode);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.isPopoverOpen', function (newValue) {
|
||||
if (newValue) {
|
||||
|
||||
let popoverElements = document.getElementsByClassName('entaxy-header-popover');
|
||||
let popoverElement = popoverElements ? popoverElements[0] : null;
|
||||
|
||||
if (popoverElement) {
|
||||
let infoSpan = document.getElementsByClassName('pficon-info')[0];
|
||||
let offsetLeft = infoSpan.offsetLeft + 18;
|
||||
|
||||
let headerTitle = document.getElementById('entaxy-header-title');
|
||||
let offsetRight = infoSpan.offsetLeft - headerTitle.offsetLeft + 12;
|
||||
|
||||
let header = document.getElementsByClassName('entaxy-header')[0];
|
||||
let isPositioningLeft = (header.offsetWidth - offsetLeft) >= offsetRight;
|
||||
|
||||
ctrl.popoverPlacement = isPositioningLeft ? 'bottom-left' : 'bottom-right';
|
||||
|
||||
popoverElement.style.maxWidth = isPositioningLeft ?
|
||||
'calc(100% - ' + offsetLeft + 'px)' : offsetRight + 'px';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function populateData(selectedNode) {
|
||||
ctrl.title = selectedNode.title;
|
||||
ctrl.objectName = selectedNode.objectName;
|
||||
|
||||
if (ctrl.objectName) {
|
||||
ctrl.isChanged = entaxyPrivateObjectsCacheService.isChanged(ctrl.objectName);
|
||||
} else {
|
||||
ctrl.isChanged = false;
|
||||
let parentNode = selectedNode.parent;
|
||||
if (parentNode && parentNode.objectName &&
|
||||
entaxyPrivateObjectsCacheService.hasAddedChildren(parentNode.objectName)) {
|
||||
let addedChildrenInfo = entaxyPrivateObjectsCacheService.getAddedObjectsInfo(parentNode.objectName);
|
||||
if (addedChildrenInfo.find(addedChildInfo =>
|
||||
selectedNode.key === parentNode.key + '-' + addedChildInfo.ui.id)) {
|
||||
ctrl.isChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entaxyHeaderController.$inject = ['workspace', '$scope', 'entaxyPrivateObjectsCacheService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,135 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyInnerObjectInput', {
|
||||
bindings: {
|
||||
model: '=',
|
||||
mode: '<',
|
||||
type: '<',
|
||||
objectFactoryFilter: '<',
|
||||
fieldName: '<',
|
||||
readonly: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="input-with-button">
|
||||
<input type="text" ng-model="$ctrl.info" ng-class="{'form-control': true}" readonly>
|
||||
<span class="pficon pficon-delete" ng-click="$ctrl.clear()" ng-if="$ctrl.model"></span>
|
||||
<button class="entaxy-view-resources-form" ng-click="$ctrl.openModal()"
|
||||
ng-if="!$ctrl.readonly || $ctrl.model">
|
||||
{{$ctrl.buttonTitle}}
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyInnerObjectInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyInnerObjectInputController(workspace, entaxyService, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
|
||||
if (ctrl.readonly) {
|
||||
ctrl.mode = Entaxy.MODAL_MODES.VIEW;
|
||||
}
|
||||
|
||||
if (ctrl.model) {
|
||||
let factory = entaxyService.getFactoryByTitle(ctrl.model.factoryId);
|
||||
ctrl.info = factory.displayName;
|
||||
ctrl.buttonTitle = ctrl.mode === Entaxy.MODAL_MODES.VIEW ?
|
||||
Entaxy.MODAL_MODES.VIEW : Entaxy.MODAL_MODES.EDIT;
|
||||
} else {
|
||||
ctrl.mode = Entaxy.MODAL_MODES.ADD;
|
||||
ctrl.buttonTitle = Entaxy.MODAL_MODES.ADD;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.openModal = function() {
|
||||
$uibModal.open({
|
||||
component: 'entaxyInnerObjectInputModal',
|
||||
resolve: {
|
||||
type: () => ctrl.type,
|
||||
mode: () => ctrl.mode,
|
||||
model: () => ctrl.model,
|
||||
fieldName: () => ctrl.fieldName,
|
||||
objectFactoryFilter: () => ctrl.objectFactoryFilter,
|
||||
outerFormController: () => ctrl.formController
|
||||
},
|
||||
backdrop: 'static',
|
||||
size: 'xl',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(args => {
|
||||
changeModelFromArgs(args);
|
||||
});
|
||||
}
|
||||
|
||||
function changeModelFromArgs(args) {
|
||||
if (ctrl.model) {
|
||||
if (ctrl.model.factoryId === args.factoryId.name) {
|
||||
args.fields.forEach(field => {
|
||||
if (field.changed) {
|
||||
ctrl.model.properties[field.name] = field.value;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ctrl.model.factoryId = args.factoryId.name;
|
||||
ctrl.model.properties = {};
|
||||
args.fields.forEach(field => {
|
||||
ctrl.model.properties[field.name] = field.value;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ctrl.model = {};
|
||||
ctrl.model.factoryId = args.factoryId.name;
|
||||
ctrl.model.scope = Entaxy.SCOPE.PRIVATE;
|
||||
ctrl.model.type = ctrl.type;
|
||||
ctrl.model.properties = {};
|
||||
args.fields.forEach(field => {
|
||||
ctrl.model.properties[field.name] = field.value;
|
||||
});
|
||||
|
||||
ctrl.mode = Entaxy.MODAL_MODES.EDIT;
|
||||
ctrl.buttonTitle = Entaxy.MODAL_MODES.EDIT;
|
||||
}
|
||||
ctrl.info = args.factoryId.displayName;
|
||||
}
|
||||
|
||||
ctrl.clear = function () {
|
||||
ctrl.model = undefined;
|
||||
ctrl.info = undefined;
|
||||
ctrl.mode = Entaxy.MODAL_MODES.ADD;
|
||||
ctrl.buttonTitle = Entaxy.MODAL_MODES.ADD;
|
||||
}
|
||||
}
|
||||
entaxyInnerObjectInputController.$inject = ['workspace', 'entaxyService', '$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,190 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyInnerObjectInputModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body-header">
|
||||
<h2>{{$ctrl.subTitle}}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="entaxyInnerObjectForm" class="form-horizontal">
|
||||
<entaxy-form-fields items="$ctrl.viewedFormFields" errors="$ctrl.errors" mode="$ctrl.mode"
|
||||
form-controller="entaxyInnerObjectForm"></entaxy-form-fields>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">{{$ctrl.buttonTitle}}</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyInnerObjectInputModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyInnerObjectInputModalController($uibModal, $scope, workspace, entaxyService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.mode = ctrl.resolve.mode;
|
||||
ctrl.model = ctrl.resolve.model;
|
||||
let extraInfo = ctrl.resolve.fieldName ? ': ' + ctrl.resolve.fieldName : '';
|
||||
ctrl.modalTitle = ctrl.mode + ' Inner Object' + extraInfo;
|
||||
ctrl.subTitle = ctrl.model ?
|
||||
ctrl.mode + ' properties of inner object' + extraInfo : 'Fill in fields' + extraInfo;
|
||||
ctrl.buttonTitle = 'Ok';
|
||||
|
||||
populateFormFields();
|
||||
}
|
||||
|
||||
function populateFormFields() {
|
||||
let promise = ctrl.resolve.objectFactoryFilter ?
|
||||
entaxyService.getFactoriesByFilterSearch(ctrl.resolve.objectFactoryFilter) :
|
||||
entaxyService.getFactoriesByType(ctrl.resolve.type);
|
||||
|
||||
promise.then(factories => {
|
||||
ctrl.factories = factories;
|
||||
let factoryId = ctrl.model ? ctrl.model.factoryId : factories[0].name;
|
||||
ctrl.populatedFactoriesFields = [factoryId];
|
||||
|
||||
ctrl.formFields = [{
|
||||
label: 'Factory',
|
||||
name: 'factoryId',
|
||||
type: 'text',
|
||||
description: factories
|
||||
.sort(Entaxy.compareBy('displayName'))
|
||||
.map(factory => factory.displayName + ' - ' + factory.description)
|
||||
.join('<br/>'),
|
||||
value: factoryId,
|
||||
readOnly: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? true : false,
|
||||
required: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? false : true,
|
||||
group: 'general',
|
||||
typeInfo: {
|
||||
type: 'enum',
|
||||
values: factories
|
||||
.map(factory => { return { displayValue: factory.displayName, value: factory.name };})
|
||||
.sort(Entaxy.compareBy('displayValue')),
|
||||
isEmptyIncluded: false
|
||||
}
|
||||
}];
|
||||
|
||||
createFormFields(factoryId);
|
||||
|
||||
addWatcher();
|
||||
});
|
||||
}
|
||||
|
||||
function createFormFields(factoryId) {
|
||||
let mbeanName = getFactoryById(factoryId).mbeanName;
|
||||
entaxyService.getFields(mbeanName)
|
||||
.then((response) => {
|
||||
let objectId = ctrl.model ? ctrl.model.objectId : undefined;
|
||||
let properties = ctrl.model ? ctrl.model.properties : undefined;
|
||||
let configurableOnly = false;
|
||||
|
||||
_.forEach(JSON.parse(response), (field) => {
|
||||
|
||||
let formField = entaxyService
|
||||
.makeFormField(field, objectId, properties, configurableOnly, ctrl.mode);
|
||||
if (formField) {
|
||||
formField.belongsToFactory = factoryId;
|
||||
ctrl.formFields.push(formField);
|
||||
}
|
||||
});
|
||||
|
||||
filterFormFields(factoryId);
|
||||
});
|
||||
}
|
||||
|
||||
function getFactoryById(factoryId) {
|
||||
return ctrl.factories.find(factory => factory.name === factoryId);
|
||||
}
|
||||
|
||||
function addWatcher() {
|
||||
$scope.$watch('$ctrl.formFields[0].value', function (newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
if (!ctrl.populatedFactoriesFields.includes(newValue)) {
|
||||
createFormFields(newValue);
|
||||
ctrl.populatedFactoriesFields.push(newValue);
|
||||
} else {
|
||||
filterFormFields(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function filterFormFields(factoryId) {
|
||||
ctrl.viewedFormFields = ctrl.formFields
|
||||
.filter(formField =>
|
||||
formField.name === 'factoryId' || formField.belongsToFactory === factoryId);
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.save = function () {
|
||||
if (ctrl.mode === Entaxy.MODAL_MODES.VIEW) {
|
||||
ctrl.cancel();
|
||||
} else {
|
||||
|
||||
let selectedFactory = ctrl.viewedFormFields.find(formField => formField.name === 'factoryId');
|
||||
|
||||
entaxyService.validateFields(ctrl.viewedFormFields, selectedFactory)
|
||||
.then(errors => {
|
||||
ctrl.errors = errors;
|
||||
|
||||
if (Object.keys(ctrl.errors).length === 0) {
|
||||
if (ctrl.resolve.outerFormController && !ctrl.resolve.outerFormController.$dirty &&
|
||||
$scope.entaxyInnerObjectForm && $scope.entaxyInnerObjectForm.$dirty) {
|
||||
ctrl.resolve.outerFormController.$setDirty();
|
||||
}
|
||||
|
||||
let args = entaxyService.getArguments(ctrl.viewedFormFields, ctrl.factories);
|
||||
|
||||
ctrl.modalInstance.close(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
entaxyInnerObjectInputModalController.$inject = ['$uibModal', '$scope', 'workspace', 'entaxyService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,59 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyInputWithExtension', {
|
||||
bindings: {
|
||||
model: '=',
|
||||
modelWithoutExtension: '=',
|
||||
extension: '<',
|
||||
readonly: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="input-with-extension">
|
||||
<input type="text" ng-model="$ctrl.modelWithoutExtension" class="form-control" ng-readonly="$ctrl.readonly"/>
|
||||
<input type="text" ng-model="$ctrl.extension" class="form-control extension-input" readonly/>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyInputWithExtensionController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyInputWithExtensionController(workspace, $scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
$scope.$watch('$ctrl.modelWithoutExtension', function () {
|
||||
ctrl.model = ctrl.modelWithoutExtension + ctrl.extension;
|
||||
})
|
||||
|
||||
}
|
||||
entaxyInputWithExtensionController.$inject = ['workspace', '$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,251 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyListInput', {
|
||||
bindings: {
|
||||
items: '=',
|
||||
itemTitleTemplate: '<',
|
||||
creationEnabled: '<',
|
||||
creationTypes: '<',
|
||||
itemFactoryFilter: '<',
|
||||
readonly: '<',
|
||||
validation: '<',
|
||||
mode: '<',
|
||||
errors: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-empty-state" ng-if="$ctrl.showEmptyState">
|
||||
<span>{{$ctrl.emptyStateMessage}}</span>
|
||||
</div>
|
||||
<div class="add-item-to-list-block" ng-click="$ctrl.showModal()"
|
||||
ng-if="$ctrl.creationEnabled && !$ctrl.readonly">
|
||||
<span class="pficon pficon-add-circle-o"></span>
|
||||
<span>{{$ctrl.addItemTitle}}</span>
|
||||
</div>
|
||||
<div as-sortable="$ctrl.dragControlListeners" ng-model="$ctrl.items"
|
||||
ng-if="$ctrl.items && $ctrl.items.length > 0">
|
||||
<div ng-repeat="item in $ctrl.items"
|
||||
ng-class="{'list-input-item-has-error': item.errors && !item.toDeletion}" as-sortable-item>
|
||||
<div class="list-input-item" ng-class="{'disabled': item.toDeletion}">
|
||||
<div class="list-input-item-heading" ng-click="$ctrl.open(item)">
|
||||
<span class="fa fa-angle-right" ng-if="!item.open"></span>
|
||||
<span class="fa fa-angle-down" ng-if="item.open"></span>
|
||||
<label ng-class="{'new-item': item.new}">
|
||||
{{$ctrl.getItemName(item.formFields)}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="list-input-item-controls" ng-if="!$ctrl.readonly">
|
||||
<span class="pficon pficon-delete remove-icon"
|
||||
ng-click="$ctrl.removeItem(item)" ng-if="!item.toDeletion"
|
||||
data-toggle="tooltip" title="Remove"></span>
|
||||
<span class="pficon pficon-history restore-icon"
|
||||
ng-click="$ctrl.restoreItem(item)" ng-if="item.toDeletion"
|
||||
data-toggle="tooltip" title="Restore"></span>
|
||||
<span class="glyphicon glyphicon-move move-icon" as-sortable-item-handle
|
||||
data-toggle="tooltip" title="Move" ng-if="!item.toDeletion"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-input-item-content" ng-show="item.open">
|
||||
<entaxy-list-item-content form-fields="item.formFields" errors="item.errors" mode="$ctrl.mode">
|
||||
</entaxy-list-item-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyListInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyListInputController(workspace, $q, $uibModal, entaxyService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.dragControlListeners = {
|
||||
itemMoved: function (event) {
|
||||
event.source.itemScope.modelValue.status = event.dest.sortableScope.$parent.column.name;
|
||||
},
|
||||
orderChanged: function (event) {
|
||||
setDirty();
|
||||
},
|
||||
containment: '#board'
|
||||
};
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.itemTypes = ctrl.creationTypes.map(type => type.displayName);
|
||||
ctrl.addItemTitle = 'Add ' + ctrl.itemTypes.join(' or ');
|
||||
|
||||
ctrl.showEmptyState = (ctrl.mode === Entaxy.MODAL_MODES.VIEW || !ctrl.creationEnabled || ctrl.readOnly)
|
||||
&& !ctrl.items || (ctrl.items && ctrl.items.length == 0);
|
||||
ctrl.emptyStateMessage = 'No Items Available';
|
||||
}
|
||||
|
||||
ctrl.getItemName = function (formFields) {
|
||||
let values = [];
|
||||
ctrl.itemTitleTemplate.fields.forEach(fieldName => {
|
||||
let formField = formFields.find(formField => formField.name === fieldName);
|
||||
values.push(formField.value);
|
||||
});
|
||||
return values.join(ctrl.itemTitleTemplate.delimiter);
|
||||
}
|
||||
|
||||
function setDirty() {
|
||||
if (ctrl.formController && !ctrl.formController.$dirty) {
|
||||
ctrl.formController.$setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.$onChanges = function (changes) {
|
||||
if (changes.errors) {
|
||||
if (ctrl.items && !changes.errors.currentValue
|
||||
&& (!changes.errors.previousValue || Object.keys(changes.errors.previousValue).length === 0)) {
|
||||
ctrl.items.forEach(item => item.errors = undefined);
|
||||
}
|
||||
if (changes.errors.currentValue) {
|
||||
let errors = changes.errors.currentValue;
|
||||
if (typeof errors !== 'string') {
|
||||
let errorKeys = Object.keys(errors);
|
||||
errorKeys.forEach(errorKey => {
|
||||
ctrl.items.filter(item => !item.toDeletion).forEach(item => {
|
||||
let formField = item.formFields.find(formField => formField.name === errorKey);
|
||||
if (formField) {
|
||||
if (errors[errorKey].values) {
|
||||
if (errors[errorKey].values.includes(formField.value)) {
|
||||
setError(item, formField.name, errors[errorKey].message);
|
||||
}
|
||||
} else {
|
||||
setError(item, formField.name, errors[errorKey].message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setError(item, formFieldName, message) {
|
||||
if (!item.errors) {
|
||||
item.errors = {};
|
||||
}
|
||||
item.errors[formFieldName] = message;
|
||||
}
|
||||
|
||||
ctrl.open = function (item) {
|
||||
if (!item.toDeletion) {
|
||||
item.open = !item.open;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.removeItem = function (item) {
|
||||
item.toDeletion = true;
|
||||
item.open = false;
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
ctrl.restoreItem = function (item) {
|
||||
item.toDeletion = false;
|
||||
}
|
||||
|
||||
ctrl.showModal = function () {
|
||||
|
||||
let allFactories = [];
|
||||
let promises = [];
|
||||
|
||||
if (ctrl.itemFactoryFilter) {
|
||||
promises.push(
|
||||
entaxyService.getFactoriesByFilterSearch(ctrl.itemFactoryFilter)
|
||||
.then(factories => allFactories = factories));
|
||||
} else {
|
||||
ctrl.creationTypes.forEach(type => {
|
||||
promises.push(
|
||||
entaxyService.getFactoriesByType(type.name)
|
||||
.then(factories => allFactories = allFactories.concat(factories)));
|
||||
});
|
||||
}
|
||||
|
||||
if (promises.length > 0) {
|
||||
|
||||
let checkUniqueness = ctrl.validation && ctrl.validation.rules && ctrl.validation.rules.checkUniqueness ?
|
||||
ctrl.validation.rules.checkUniqueness : undefined;
|
||||
let checkUniquenessFields = {};
|
||||
if (checkUniqueness) {
|
||||
checkUniqueness.fields.forEach(field => {
|
||||
checkUniquenessFields[field] = [];
|
||||
if (ctrl.items) {
|
||||
ctrl.items.forEach(item => {
|
||||
let formField = item.formFields.find(formField => formField.name === field);
|
||||
checkUniquenessFields[field].push(formField.value);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyModal',
|
||||
resolve: {
|
||||
mode: () => Entaxy.MODAL_MODES.ADD,
|
||||
itemType: () => ctrl.itemTypes.join(' or '),
|
||||
factories: $q.all(promises).then(() => allFactories),
|
||||
returnFormFields: () => true,
|
||||
checkUniquenessParentFields: () => checkUniquenessFields
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(formFields => {
|
||||
addItem(formFields);
|
||||
},
|
||||
reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addItem(formFields) {
|
||||
|
||||
if (!ctrl.items) {
|
||||
ctrl.items = [];
|
||||
}
|
||||
|
||||
ctrl.items.push({
|
||||
new: true,
|
||||
formFields: formFields
|
||||
});
|
||||
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
entaxyListInputController.$inject = ['workspace', '$q', '$uibModal', 'entaxyService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,79 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyListItemContent', {
|
||||
bindings: {
|
||||
formFields: '<',
|
||||
mode: '<',
|
||||
errors: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<uib-tabset active="$ctrl.selectedGroupIndex">
|
||||
<uib-tab ng-repeat="group in $ctrl.groups track by $index"
|
||||
heading="{{group.displayName}}" select="$ctrl.change()">
|
||||
<entaxy-form-fields items="group.formFields" errors="$ctrl.errors" mode="$ctrl.mode">
|
||||
</entaxy-form-fields>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
||||
`,
|
||||
controller: EntaxyListItemContentController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyListItemContentController() {
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
let groups = new Set();
|
||||
groups.add('general');
|
||||
|
||||
ctrl.formFields.forEach(formField => {
|
||||
groups.add(formField.group);
|
||||
});
|
||||
|
||||
ctrl.groups = Array.from(groups).map((group) => {
|
||||
return {
|
||||
name: group,
|
||||
displayName: group,
|
||||
formFields: ctrl.formFields.filter(formField => formField.group === group)
|
||||
};
|
||||
});
|
||||
|
||||
if (ctrl.errors) {
|
||||
let errorFields = Object.keys(ctrl.errors);
|
||||
for (let i = 0; i < ctrl.groups.length; i++) {
|
||||
if (ctrl.groups[i].formFields.find(formField => errorFields.includes(formField.name))) {
|
||||
ctrl.selectedGroupIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,204 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyMapInput', {
|
||||
bindings: {
|
||||
model: '=',
|
||||
items: '=',
|
||||
duplicateKeys: '=',
|
||||
hasErrors: '=',
|
||||
readonly: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-map-input-table" ng-if="$ctrl.items && $ctrl.items.length > 0">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr role="row" ng-repeat="field in $ctrl.items">
|
||||
<td class="input-cell">
|
||||
<input type="text" class="form-control" ng-model="field.key" ng-change="$ctrl.changeKey(field)"
|
||||
ng-class="{'has-error': field.hasError}" ng-readonly="$ctrl.readonly || field.removed"/>
|
||||
</td>
|
||||
<td class="input-cell">
|
||||
<input type="text" class="form-control" ng-model="field.value" ng-change="$ctrl.changeValue(field)"
|
||||
ng-readonly="$ctrl.readonly || field.removed"/>
|
||||
</td>
|
||||
<td ng-if="!$ctrl.readonly">
|
||||
<button type="button" ng-click="$ctrl.remove(field)" data-toggle="tooltip" title="Remove"
|
||||
ng-if="!field.removed">
|
||||
<span class="pficon pficon-delete"></span>
|
||||
</button>
|
||||
<button type="button" ng-click="$ctrl.restore(field)" data-toggle="tooltip" title="Restore"
|
||||
ng-if="field.removed">
|
||||
<span class="pficon pficon-history"></span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<input type="text" class="form-control" ng-model="$ctrl.emptyValueInfo" ng-if="$ctrl.emptyValueInfo" readonly/>
|
||||
<button type="button" class="entaxy-map-input-add-button" ng-if="!$ctrl.readonly" ng-click="$ctrl.add()">
|
||||
<span class="pficon pficon-add-circle-o"></span>
|
||||
<span>{{$ctrl.addItemTitle}}</span>
|
||||
</button>
|
||||
`,
|
||||
controller: entaxyMapInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyMapInputController() {
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
ctrl.addItemTitle = 'Add Property';
|
||||
if (!ctrl.items) {
|
||||
if (ctrl.model) {
|
||||
ctrl.items = Object.entries(ctrl.model).map(([key, value]) => {
|
||||
return {
|
||||
key: key,
|
||||
value: value
|
||||
};
|
||||
}).sort(Entaxy.compareBy('key'));
|
||||
} else {
|
||||
ctrl.items = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrl.items.length === 0 && ctrl.readonly) {
|
||||
ctrl.emptyValueInfo = '--Map is empty--';
|
||||
}
|
||||
|
||||
if (!ctrl.duplicateKeys) {
|
||||
ctrl.duplicateKeys = new Set();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.changeKey = function (field) {
|
||||
validateKey(field);
|
||||
updateDuplicatesStatus();
|
||||
updateErrorsState();
|
||||
|
||||
updateModel();
|
||||
}
|
||||
|
||||
ctrl.changeValue = function (field) {
|
||||
updateModel();
|
||||
}
|
||||
|
||||
function validateKey(field) {
|
||||
if (field.key.trim().length === 0) {
|
||||
field.hasError = true;
|
||||
} else {
|
||||
let duplicates = getItemsByKey(field.key);
|
||||
|
||||
if (duplicates.length > 1) {
|
||||
ctrl.duplicateKeys.add(field.key);
|
||||
duplicates.forEach(item => item.hasError = true);
|
||||
} else {
|
||||
field.hasError = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateDuplicatesStatus() {
|
||||
let expiredDuplicateKeys = new Set();
|
||||
ctrl.duplicateKeys.forEach(duplicateKey => {
|
||||
let duplicates = getItemsByKey(duplicateKey);
|
||||
|
||||
if (duplicates.length <= 1) {
|
||||
expiredDuplicateKeys.add(duplicateKey);
|
||||
duplicates.forEach(item => item.hasError = false);
|
||||
}
|
||||
});
|
||||
if (expiredDuplicateKeys.size === ctrl.duplicateKeys.size) {
|
||||
ctrl.duplicateKeys.clear();
|
||||
} else {
|
||||
expiredDuplicateKeys.forEach(expiredDuplicateKey => ctrl.duplicateKeys.delete(expiredDuplicateKey));
|
||||
}
|
||||
}
|
||||
|
||||
function getItemsByKey(key) {
|
||||
return ctrl.items.filter(item => !item.removed && item.key === key);
|
||||
}
|
||||
|
||||
function updateErrorsState() {
|
||||
ctrl.hasErrors = ctrl.items.filter(item => !item.removed && item.hasError).length === 0 ? false : true;
|
||||
}
|
||||
|
||||
function updateModel() {
|
||||
if (!ctrl.hasErrors) {
|
||||
ctrl.model = ctrl.items.length > 0 ? {} : undefined;
|
||||
ctrl.items.forEach(item => {
|
||||
if (!item.removed && !item.hasError) {
|
||||
ctrl.model[item.key] = item.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.add = function () {
|
||||
ctrl.items.push({type: 'text', key: '', value: ''});
|
||||
validateKey(ctrl.items[ctrl.items.length - 1]);
|
||||
updateErrorsState();
|
||||
|
||||
ctrl.setDirty();
|
||||
}
|
||||
|
||||
ctrl.remove = function (field) {
|
||||
field.removed = true;
|
||||
field.hasError = false;
|
||||
|
||||
updateDuplicatesStatus();
|
||||
updateErrorsState();
|
||||
|
||||
updateModel();
|
||||
|
||||
ctrl.setDirty();
|
||||
}
|
||||
|
||||
ctrl.restore = function (field) {
|
||||
field.removed = false;
|
||||
|
||||
validateKey(field);
|
||||
updateDuplicatesStatus();
|
||||
updateErrorsState();
|
||||
|
||||
updateModel();
|
||||
|
||||
ctrl.setDirty();
|
||||
}
|
||||
|
||||
ctrl.setDirty = function () {
|
||||
if (ctrl.formController && !ctrl.formController.$dirty) {
|
||||
ctrl.formController.$setDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,110 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyPasswordInput', {
|
||||
bindings: {
|
||||
name: '<',
|
||||
model: '=',
|
||||
confirmationModel: '=',
|
||||
ignoreConfirmationValue: '=',
|
||||
readonly: '<',
|
||||
errors: '='
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="password-input">
|
||||
<input type="{{$ctrl.type}}" class="form-control" ng-model="$ctrl.model" ng-readonly="$ctrl.readonly"
|
||||
autocomplete="new-password">
|
||||
<span ng-class="{'fa fa-eye': !$ctrl.isVisible(), 'fa fa-eye-slash': $ctrl.isVisible()}"
|
||||
ng-click="$ctrl.view()"></span>
|
||||
</div>
|
||||
<input type="{{$ctrl.type}}" class="form-control confirmation-password-input"
|
||||
ng-model="$ctrl.confirmationModel" ng-if="!$ctrl.readonly"
|
||||
placeholder="confirm password here" ng-show="$ctrl.model && !$ctrl.ignoreConfirmationValue">
|
||||
`,
|
||||
controller: entaxyPasswordInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyPasswordInputController($scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
const TYPES = {
|
||||
PASSWORD: 'password',
|
||||
TEXT: 'text'
|
||||
}
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.type = TYPES.PASSWORD;
|
||||
}
|
||||
|
||||
ctrl.view = function () {
|
||||
ctrl.type = ctrl.isVisible() ? TYPES.PASSWORD : TYPES.TEXT;
|
||||
}
|
||||
|
||||
ctrl.isVisible = function () {
|
||||
return ctrl.type !== TYPES.PASSWORD;
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.model', function () {
|
||||
if (ctrl.ignoreConfirmationValue && ctrl.valueAssigned) {
|
||||
ctrl.ignoreConfirmationValue = false;
|
||||
}
|
||||
if (!ctrl.ignoreConfirmationValue) {
|
||||
validate();
|
||||
} else {
|
||||
ctrl.valueAssigned = true;
|
||||
}
|
||||
})
|
||||
|
||||
$scope.$watch('$ctrl.confirmationModel', function () {
|
||||
if (!ctrl.ignoreConfirmationValue) {
|
||||
validate();
|
||||
}
|
||||
});
|
||||
|
||||
function validate() {
|
||||
let message = Entaxy.ERROR_MESSAGE.PASSWORD_CONFIRMATION;
|
||||
if (ctrl.errors) {
|
||||
if (ctrl.model && ctrl.model !== ctrl.confirmationModel) {
|
||||
ctrl.errors[ctrl.name] = message;
|
||||
} else {
|
||||
if (ctrl.errors[ctrl.name] === message) {
|
||||
ctrl.errors[ctrl.name] = undefined;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ctrl.confirmationModel !== ctrl.model) {
|
||||
ctrl.errors = {[ctrl.name]: message};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entaxyPasswordInputController.$inject = ['$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,72 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyResourceInput', {
|
||||
bindings: {
|
||||
name: '@',
|
||||
model: '=',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-resource-input" entaxy-file-drop ng-model="$ctrl.file" ng-click="$ctrl.triggerUpload()">
|
||||
<span class="fa fa-upload"></span>
|
||||
<span ng-if="!$ctrl.file">Drop file to upload</span>
|
||||
<span ng-if="$ctrl.file">
|
||||
File {{($ctrl.file.name | limitTo: 15) + ($ctrl.file.name.length > 15 ? '...' : '')}} is ready to upload
|
||||
</span>
|
||||
<input type="file" id="{{$ctrl.name}}-file-input" set-file-model ng-model="$ctrl.file">
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyResourceInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyResourceInputController(workspace, $scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
if (ctrl.model) {
|
||||
ctrl.file = ctrl.model;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.file', function () {
|
||||
ctrl.model = ctrl.file;
|
||||
});
|
||||
|
||||
ctrl.triggerUpload = function () {
|
||||
document.getElementById(ctrl.name + '-file-input').click();
|
||||
}
|
||||
|
||||
}
|
||||
entaxyResourceInputController.$inject = ['workspace', '$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,239 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxySelect', {
|
||||
bindings: {
|
||||
type: '<',
|
||||
filter: '<',
|
||||
model: '=',
|
||||
readonly: '<',
|
||||
updateParent: '<',
|
||||
updateParentFn: '<',
|
||||
options: '=',
|
||||
creationEnabled: '<',
|
||||
isEmptyIncluded: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="custom-select" ng-if="!$ctrl.readonly">
|
||||
<button type="button" class="btn-select form-control dropdown-toggle" id="filter"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="selected-option">{{$ctrl.selectedOption.displayName}}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="option in $ctrl.options" id="option.name" ng-click="$ctrl.changeSelection(option)">
|
||||
{{ option.displayName }}
|
||||
</li>
|
||||
<li id="addItem" class="dropdown-option-new" ng-click="$ctrl.showModal()" ng-if="$ctrl.creationEnabled">
|
||||
<span class="pficon pficon-add-circle-o"></span>
|
||||
{{$ctrl.createObjectOptionTitle}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="text" class="form-control" ng-model="$ctrl.selectedOption.displayName"
|
||||
ng-if="$ctrl.readonly" readonly>
|
||||
`,
|
||||
controller: entaxySelectController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxySelectController(workspace, jolokiaService, jolokia, $q, $uibModal, entaxyService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let emptyValue;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
if (!ctrl.readonly) {
|
||||
|
||||
ctrl.itemType = Entaxy.getItemTypeFromRuntimeType(ctrl.type);
|
||||
|
||||
if (ctrl.creationEnabled) {
|
||||
ctrl.createObjectOptionTitle = 'New private ' + ctrl.itemType + '...';
|
||||
}
|
||||
|
||||
populateOptions();
|
||||
} else {
|
||||
let domain = entaxyService.getDomainFolder();
|
||||
entaxyService.getAllChildMBeansByRuntimeType(domain, ctrl.type).then((mbeans) => {
|
||||
|
||||
let mbean = mbeans.find(mbean => mbean.attributes.Name === ctrl.model);
|
||||
|
||||
ctrl.selectedOption = mbean ? createOptionFromMbean(mbean) : { displayName: ctrl.model };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function populateOptions() {
|
||||
if (!ctrl.options) {
|
||||
|
||||
let emptyOptionName = '--No ' + ctrl.itemType + ' selected--';
|
||||
emptyValue = {name: emptyOptionName, displayName: emptyOptionName};
|
||||
|
||||
let domain = entaxyService.getDomainFolder();
|
||||
if (ctrl.filter) {
|
||||
entaxyService.findObjectsByFilter(ctrl.filter).then(result => {
|
||||
let objectFullIds = JSON.parse(result);
|
||||
|
||||
entaxyService.getMBeansByObjectFullIds(objectFullIds).then((mbeans) => {
|
||||
populateOptionsFromMbeans(mbeans);
|
||||
});
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
Entaxy.log.error(error);
|
||||
});
|
||||
} else {
|
||||
entaxyService.getAllChildMBeansByRuntimeType(domain, ctrl.type).then((mbeans) => {
|
||||
populateOptionsFromMbeans(mbeans);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (ctrl.isEmptyIncluded) {
|
||||
emptyValue = ctrl.options[0];
|
||||
}
|
||||
ctrl.selectedOption = getOptionByModel();
|
||||
}
|
||||
}
|
||||
|
||||
function populateOptionsFromMbeans(mbeans) {
|
||||
let items = mbeans.map(mbean => createOptionFromMbean(mbean));
|
||||
|
||||
if (items && items.length > 0) {
|
||||
ctrl.options = items.sort(Entaxy.compareBy('displayName'));
|
||||
|
||||
if (ctrl.isEmptyIncluded) {
|
||||
ctrl.options.unshift(emptyValue);
|
||||
}
|
||||
|
||||
ctrl.changeSelection(ctrl.model ? getOptionByModel() : items[0]);
|
||||
} else {
|
||||
ctrl.options = [];
|
||||
let notificationType = ctrl.creationEnabled ?
|
||||
Entaxy.NOTIFICATION_TYPE.WARNING : Entaxy.NOTIFICATION_TYPE.DANGER;
|
||||
Core.notification(notificationType, 'There is no suitable ' + ctrl.itemType.toLowerCase(),
|
||||
Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_ERROR]);
|
||||
// todo close the modal if creation is disabled
|
||||
}
|
||||
}
|
||||
|
||||
function createOptionFromMbean(mbean) {
|
||||
let displayName = mbean.attributes.DisplayName;
|
||||
let name = mbean.attributes.Name;
|
||||
|
||||
return {
|
||||
name: name,
|
||||
displayName: createDisplayName(displayName, name),
|
||||
mbeanName: mbean.mbean.objectName
|
||||
};
|
||||
}
|
||||
|
||||
function createDisplayName(displayName, name) {
|
||||
return displayName && displayName !== name ? displayName + ' [' + name + ']' : name;
|
||||
}
|
||||
|
||||
function getOptionByModel() {
|
||||
return ctrl.options.find((option) => option.name === ctrl.model || option.value === ctrl.model);
|
||||
}
|
||||
|
||||
ctrl.changeSelection = function (option) {
|
||||
if (ctrl.selectedOption !== option) {
|
||||
let previousOption = ctrl.selectedOption;
|
||||
ctrl.selectedOption = option;
|
||||
ctrl.model = option.name === emptyValue.name ? undefined : (option.value ? option.value : option.name);
|
||||
|
||||
if (previousOption && ctrl.formController && !ctrl.formController.$dirty) {
|
||||
ctrl.formController.$setDirty();
|
||||
}
|
||||
|
||||
if (ctrl.updateParent) {
|
||||
if (previousOption) {
|
||||
Core.notification(Entaxy.NOTIFICATION_TYPE.WARNING,
|
||||
'Changing ' + ctrl.itemType +
|
||||
' field value may lead to changes in other fields of the current object. ' +
|
||||
'Please, make sure to revise all fields before accepting.',
|
||||
Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_INFO]);
|
||||
}
|
||||
ctrl.updateParentFn(previousOption, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.showModal = function() {
|
||||
$uibModal.open({
|
||||
component: 'entaxyModal',
|
||||
resolve: {
|
||||
mode: () => Entaxy.MODAL_MODES.ADD,
|
||||
itemType: () => Entaxy.capitalize(ctrl.itemType),
|
||||
factories: entaxyService.getFactoriesByType(ctrl.type, ctrl.filter).then(factories => factories)
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(args => {
|
||||
addItem(args);
|
||||
},
|
||||
reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addItem(args) {
|
||||
|
||||
let factoryId = args.factoryId.name;
|
||||
|
||||
let objectId = args.fields.find((field) => field.name === 'objectId').value;
|
||||
|
||||
let fields = objectId ? args.fields.filter((field) => field.name !== 'objectId') : args.fields;
|
||||
|
||||
let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});
|
||||
|
||||
let newObjectProperties = {
|
||||
factoryId: factoryId,
|
||||
objectId: objectId,
|
||||
scope: 'private',
|
||||
properties: properties
|
||||
};
|
||||
|
||||
let newObjectOption = {
|
||||
name: objectId ? objectId : ('private-' + ctrl.itemType),
|
||||
value: newObjectProperties
|
||||
};
|
||||
|
||||
ctrl.options.push(newObjectOption);
|
||||
ctrl.changeSelection(newObjectOption);
|
||||
}
|
||||
}
|
||||
entaxySelectController.$inject = ['workspace', 'jolokiaService', 'jolokia', '$q', '$uibModal', 'entaxyService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,113 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxySelectFromEnum', {
|
||||
bindings: {
|
||||
values: '<',
|
||||
isEmptyIncluded: '<',
|
||||
emptyOptionName: '<',
|
||||
model: '=',
|
||||
readonly: '<',
|
||||
multiple: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<select class="form-control" ng-options="option.displayName for option in $ctrl.options"
|
||||
ng-model="$ctrl.selectedOption" ng-change="$ctrl.changeSelection()" ng-disabled="$ctrl.readonly">
|
||||
`,
|
||||
controller: entaxySelectFromEnumController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxySelectFromEnumController($scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let emptyValue = { name: '--Empty value--' };
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
emptyValue.displayName = ctrl.emptyOptionName ? ctrl.emptyOptionName : emptyValue.name;
|
||||
populateOptions();
|
||||
if (ctrl.options.length == 1 || (!ctrl.isEmptyIncluded && !ctrl.model)) {
|
||||
ctrl.selectedOption = ctrl.options[0];
|
||||
ctrl.changeSelection();
|
||||
}
|
||||
}
|
||||
|
||||
function populateOptions() {
|
||||
ctrl.options = (ctrl.values && ctrl.values.length > 0) ?
|
||||
ctrl.values.map(value => {
|
||||
return angular.isObject(value) ?
|
||||
{ displayName: value.displayValue ? value.displayValue : value.value, name: value.value } :
|
||||
{ displayName: value, name: value }
|
||||
}) : [];
|
||||
|
||||
if (ctrl.isEmptyIncluded !== false) {
|
||||
ctrl.options.unshift(emptyValue);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watchCollection('$ctrl.values', function(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
populateOptions();
|
||||
|
||||
let currentSelectedOption = ctrl.options.find((option) => option.name === ctrl.selectedOption.name);
|
||||
ctrl.selectedOption = currentSelectedOption ? currentSelectedOption : ctrl.options[0];
|
||||
|
||||
ctrl.changeSelection();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('$ctrl.model', function() {
|
||||
if (ctrl.multiple) {
|
||||
if (ctrl.model && ctrl.model.length > 0) {
|
||||
if (!ctrl.selectedOption || ctrl.selectedOption.name !== ctrl.model[0]) {
|
||||
ctrl.selectedOption = ctrl.options.find((option) => option.name === ctrl.model[0]);
|
||||
}
|
||||
} else {
|
||||
if (!ctrl.selectedOption || ctrl.selectedOption.name !== ctrl.options[0].name) {
|
||||
ctrl.selectedOption = ctrl.options[0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctrl.selectedOption = ctrl.model ?
|
||||
ctrl.options.find((option) => option.name === ctrl.model) : ctrl.options[0];
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.changeSelection = function () {
|
||||
if (ctrl.selectedOption.name === emptyValue.name) {
|
||||
ctrl.model = ctrl.multiple ? [] : undefined;
|
||||
} else {
|
||||
ctrl.model = ctrl.multiple ? [ctrl.selectedOption.name] : ctrl.selectedOption.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
entaxySelectFromEnumController.$inject = ['$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,81 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyUrlInput', {
|
||||
bindings: {
|
||||
model: '=',
|
||||
config: '<',
|
||||
readonly: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="input-with-button">
|
||||
<input type="text" ng-model="$ctrl.model" ng-class="{'form-control': true}" readonly>
|
||||
<span class="pficon pficon-delete" ng-click="$ctrl.clear()" ng-if="$ctrl.model"></span>
|
||||
<button class="entaxy-view-resources-form" ng-click="$ctrl.openViewer()" ng-if="!$ctrl.readonly">
|
||||
Select...
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyUrlInputController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyUrlInputController(workspace, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.openViewer = function() {
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyResourceViewerModal',
|
||||
resolve: {
|
||||
location: () => ctrl.model,
|
||||
config: () => ctrl.config
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(location => {
|
||||
if (ctrl.model !== location && ctrl.formController && !ctrl.formController.$dirty) {
|
||||
ctrl.formController.$setDirty();
|
||||
}
|
||||
ctrl.model = location;
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.clear = function () {
|
||||
ctrl.model = undefined;
|
||||
}
|
||||
}
|
||||
entaxyUrlInputController.$inject = ['workspace', '$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,79 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyXml', {
|
||||
bindings: {
|
||||
ngModel: '=',
|
||||
mode: '<',
|
||||
readonly: '<',
|
||||
formController: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<button class="entaxy-xml-form" ng-click="$ctrl.openEditor()" ng-disabled="$ctrl.disabled">
|
||||
{{$ctrl.buttonTitle}}
|
||||
</button>
|
||||
`,
|
||||
controller: entaxyXmlController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyXmlController(workspace, $scope, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
$scope.$watch('$ctrl.readonly', function () {
|
||||
ctrl.buttonTitle = ctrl.readonly ? Entaxy.MODAL_MODES.VIEW : ctrl.mode;
|
||||
ctrl.disabled = ctrl.readonly &&
|
||||
(ctrl.ngModel === undefined || (angular.isString(ctrl.ngModel) && ctrl.ngModel.trim().length === 0));
|
||||
});
|
||||
|
||||
ctrl.openEditor = function() {
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyXmlModal',
|
||||
resolve: {
|
||||
xml: () => ctrl.ngModel,
|
||||
mode: () => ctrl.readonly ? Entaxy.MODAL_MODES.VIEW : ctrl.mode
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(xml => {
|
||||
if (ctrl.ngModel !== xml && ctrl.formController && !ctrl.formController.$dirty) {
|
||||
ctrl.formController.$setDirty();
|
||||
}
|
||||
ctrl.ngModel = xml;
|
||||
});
|
||||
}
|
||||
}
|
||||
entaxyXmlController.$inject = ['workspace', '$scope', '$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,214 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyAddConnectorModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
<div ng-if="$ctrl.step1 && $ctrl.profiles">
|
||||
<div class="modal-body-header">
|
||||
<h2>Choose profile to attach connector to</h2>
|
||||
</div>
|
||||
<div class="modal-body" style="height:433px; max-height:433px">
|
||||
<entaxy-modal-list items="$ctrl.profiles" selected="$ctrl.selectedProfile"
|
||||
change-selection="$ctrl.changeProfileSelection" enable-dbl-click="true"></entaxy-modal-list>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.next()"
|
||||
ng-disabled="!$ctrl.selectedProfile">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="$ctrl.step2">
|
||||
<div class="modal-body-header">
|
||||
<h2>Choose connector template</h2>
|
||||
</div>
|
||||
<div class="modal-body" style="height:433px; max-height:433px">
|
||||
<entaxy-modal-list items="$ctrl.templates" selected="$ctrl.selectedTemplate"
|
||||
change-selection="$ctrl.changeTemplateSelection" enable-dbl-click="true"></entaxy-modal-list>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.back()" ng-if="$ctrl.profiles">Back</button>
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.next()"
|
||||
ng-disabled="!$ctrl.selectedTemplate">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<form name="connectorForm" class="form-horizontal" ng-if="$ctrl.step3" ng-submit="$ctrl.saveConnector($ctrl.formFields)">
|
||||
<div class="modal-body" style="height:503px; max-height:503px;">
|
||||
<div class="modal-body-header">
|
||||
<h2>Fill in connector template parameters</h2>
|
||||
</div>
|
||||
<div class="form-group" ng-class="{'has-error': $ctrl.errors[formField.name]}"
|
||||
ng-repeat="formField in $ctrl.formFields" style="margin:15px;">
|
||||
<label class="col-sm-3 control-label" ng-class="{'required-pf': formField.isRequired}" for="{{formField.name}}">{{formField.label}}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="{{formField.type}}" id="{{formField.name}}" ng-class="{'form-control': formField.type !== 'checkbox'}"
|
||||
ng-model="formField.value" ng-readonly="formField.isReadOnly" ng-if="!formField.typeInfo">
|
||||
<span class="help-block" ng-show="$ctrl.errors[formField.name]">{{$ctrl.errors[formField.name]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.back()">Back</button>
|
||||
<button type="submit" class="btn btn-primary">Add</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyAddConnectorModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyAddConnectorModalController(workspace, jolokia) {
|
||||
'ngInject';
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
let templates = Entaxy.getConnectorTemplates();
|
||||
ctrl.templates = templates.map(template => { return { name: template, displayName: template }});
|
||||
|
||||
ctrl.profiles = ctrl.resolve.profiles;
|
||||
|
||||
if (ctrl.profiles) {
|
||||
ctrl.step1 = true;
|
||||
ctrl.step2 = false;
|
||||
ctrl.step3 = false;
|
||||
} else {
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = true;
|
||||
ctrl.step3 = false;
|
||||
}
|
||||
|
||||
ctrl.modalTitle = ctrl.resolve.profileName ?
|
||||
'Add Legacy Connector to ' + ctrl.resolve.profileName : 'Add Legacy Connector';
|
||||
}
|
||||
|
||||
ctrl.changeProfileSelection = function(item, isDblClicked) {
|
||||
ctrl.selectedProfile = item;
|
||||
if (isDblClicked) {
|
||||
ctrl.next();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.changeTemplateSelection = function(item, isDblClicked) {
|
||||
ctrl.selectedTemplate = item;
|
||||
if (isDblClicked) {
|
||||
ctrl.next();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.next = function() {
|
||||
if (ctrl.step1 === true) {
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = true;
|
||||
} else if (ctrl.step2 === true) {
|
||||
ctrl.step2 = false;
|
||||
ctrl.step3 = true;
|
||||
}
|
||||
|
||||
if (ctrl.step3 === true) {
|
||||
defineFormFields();
|
||||
}
|
||||
}
|
||||
|
||||
function defineFormFields() {
|
||||
if (!ctrl.formFields || ctrl.selectedTemplate.name !== ctrl.formFields[0].value) {
|
||||
ctrl.formFields = Entaxy.getConnectorTemplateParams(ctrl.selectedTemplate.name);
|
||||
|
||||
ctrl.formFields.unshift({
|
||||
label: 'templateName',
|
||||
displayName: 'Template Name',
|
||||
type: 'java.lang.String',
|
||||
helpText: null,
|
||||
value: ctrl.selectedTemplate.name,
|
||||
isReadOnly: true
|
||||
});
|
||||
ctrl.formFields.forEach(formField => {
|
||||
formField.name = formField.label;
|
||||
if (formField.displayName) {
|
||||
formField.label = formField.displayName;
|
||||
}
|
||||
formField.type = Entaxy.convertToHtmlInputType(formField.type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.back = function() {
|
||||
if (ctrl.step2 === true) {
|
||||
ctrl.step1 = true;
|
||||
ctrl.step2 = false;
|
||||
} else if (ctrl.step3 === true) {
|
||||
ctrl.step2 = true;
|
||||
ctrl.step3 = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.cancel = function() {
|
||||
ctrl.modalInstance.dismiss();
|
||||
}
|
||||
|
||||
ctrl.saveConnector = function(fields) {
|
||||
ctrl.errors = validateFields(fields);
|
||||
|
||||
if (Object.keys(ctrl.errors).length === 0) {
|
||||
let connectorArgs = {
|
||||
profile: ctrl.selectedProfile,
|
||||
connectorTemplateName: ctrl.formFields.shift().value,
|
||||
connectorFields: ctrl.formFields.map(formField => { return { label: formField.name, value: formField.value }; })
|
||||
};
|
||||
|
||||
ctrl.modalInstance.close(connectorArgs);
|
||||
}
|
||||
}
|
||||
|
||||
function validateFields(fields) {
|
||||
let errors = {};
|
||||
|
||||
_.forEach(fields, (field) => {
|
||||
if (field.isRequired &&
|
||||
(!field.value || (field.type !== 'checkbox' ? field.value.toString().trim().length === 0 : false))) {
|
||||
errors[field.name] = Entaxy.ERROR_MESSAGE.EMPTY;
|
||||
}
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
EntaxyAddConnectorModalController.$inject = ['workspace', 'jolokia'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,77 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyConfirmationModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-simple-modal-container message-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body-small">
|
||||
<span class="simple-modal-message">
|
||||
{{$ctrl.message}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.confirm()">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyConfirmationModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyConfirmationModalController($uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.title = ctrl.resolve.title;
|
||||
ctrl.message = ctrl.resolve.message;
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.confirm = function() {
|
||||
ctrl.modalInstance.close(true);
|
||||
}
|
||||
}
|
||||
entaxyConfirmationModalController.$inject = ['$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,346 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.step1">
|
||||
<div class="modal-body-header">
|
||||
<h2>{{$ctrl.firstStepTitle}}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<entaxy-modal-list items="$ctrl.profiles" selected="$ctrl.selectedProfile"
|
||||
change-selection="$ctrl.changeProfileSelection" enable-dbl-click="true"></entaxy-modal-list>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.next()" ng-disabled="!$ctrl.selectedProfile">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.step2">
|
||||
<div class="modal-body-header">
|
||||
<h2>{{$ctrl.secondStepTitle}}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<entaxy-modal-list-with-description items="$ctrl.factories" selected-item="$ctrl.selectedFactory"
|
||||
change-selection="$ctrl.changeFactorySelection" show-deprecated="$ctrl.showDeprecated">
|
||||
</entaxy-modal-list-with-description>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-if="$ctrl.profiles" ng-click="$ctrl.back()">Back</button>
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.next()" ng-disabled="!$ctrl.selectedFactory">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="$ctrl.step3">
|
||||
<div class="modal-body-header form-header">
|
||||
<h2>{{$ctrl.thirdStepTitle}}</h2>
|
||||
<span ng-if="$ctrl.shouldShowChangesNote()">
|
||||
There are unsaved changes
|
||||
</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<entaxy-modal-group-fields groups="$ctrl.groups" fields="$ctrl.formFields"
|
||||
use-form-dirty="true" is-form-dirty="$ctrl.isFormDirty"
|
||||
errors="$ctrl.errors" mode="$ctrl.mode"></entaxy-modal-group-fields>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-if="$ctrl.factories.length > 1 || $ctrl.profiles" ng-click="$ctrl.back()">Back</button>
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">{{$ctrl.submitBtnTitle}}</button>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyModalController($scope, entaxyService, entaxyPrivateObjectsCacheService, entaxyProfileDiagramService) {
|
||||
'ngInject';
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.mode = ctrl.resolve.mode;
|
||||
|
||||
if (!ctrl.mode) {
|
||||
ctrl.cancel('Mode is not defined');
|
||||
}
|
||||
|
||||
ctrl.hasChangedPrivateObjects = ctrl.mode !== Entaxy.MODAL_MODES.ADD ?
|
||||
entaxyPrivateObjectsCacheService.isChanged(ctrl.resolve.itemMbeanName) : false;
|
||||
|
||||
ctrl.hasChangesFromDiagram = ctrl.mode === Entaxy.MODAL_MODES.EDIT ?
|
||||
entaxyProfileDiagramService.hasChanges(ctrl.resolve.itemMbeanName) : false;
|
||||
|
||||
ctrl.itemType = ctrl.resolve.itemType ? ctrl.resolve.itemType : 'Item';
|
||||
|
||||
let extraToTitle = ctrl.resolve.parentName ? (' to ' + ctrl.resolve.parentName) : '';
|
||||
|
||||
ctrl.modalTitle = ctrl.mode + ' ' + ctrl.itemType + extraToTitle;
|
||||
|
||||
ctrl.submitBtnTitle = Entaxy.getButtonTitleByMode(ctrl.mode);
|
||||
|
||||
let itemName = ctrl.resolve.itemName;
|
||||
|
||||
ctrl.firstStepTitle = 'Choose profile to attach connector to';
|
||||
|
||||
ctrl.secondStepTitle = ctrl.resolve.secondStepTitle ? ctrl.resolve.secondStepTitle : 'Choose factory';
|
||||
|
||||
ctrl.thirdStepTitle = itemName ? ctrl.mode + ' properties for ' + itemName
|
||||
: ctrl.resolve.thirdStepTitle ? ctrl.resolve.thirdStepTitle : 'Fill in fields';
|
||||
|
||||
if (ctrl.mode !== Entaxy.MODAL_MODES.ADD) {
|
||||
ctrl.properties = ctrl.resolve.info.properties;
|
||||
ctrl.configurableOnly = ctrl.resolve.info.configurableOnly;
|
||||
}
|
||||
|
||||
ctrl.profiles = ctrl.resolve.profiles;
|
||||
|
||||
ctrl.factories = ctrl.resolve.factories ? ctrl.resolve.factories : null;
|
||||
|
||||
if (!ctrl.factories || ctrl.factories.length === 0) {
|
||||
ctrl.cancel('Factories are not found');
|
||||
}
|
||||
|
||||
ctrl.factories.sort(Entaxy.compareBy('displayName'));
|
||||
|
||||
if (ctrl.profiles) {
|
||||
ctrl.step1 = true;
|
||||
ctrl.step2 = false;
|
||||
ctrl.step3 = false
|
||||
} else {
|
||||
if (ctrl.factories.length > 1) {
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = true;
|
||||
ctrl.step3 = false;
|
||||
} else if (ctrl.factories.length === 1) {
|
||||
ctrl.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.next = function() {
|
||||
|
||||
if (ctrl.step1 === true) {
|
||||
if (ctrl.factories.length > 1) {
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = true;
|
||||
} else if (ctrl.factories.length === 1) {
|
||||
defineFormFields();
|
||||
}
|
||||
} else {
|
||||
defineFormFields();
|
||||
}
|
||||
}
|
||||
|
||||
function defineFormFields() {
|
||||
let container = ctrl.formFields ? ctrl.formFields.find(field => field.name === '__entaxyContainerId') : undefined;
|
||||
|
||||
if (!ctrl.formFields || ctrl.selectedFactory.name !== ctrl.formFields[0].value
|
||||
|| (ctrl.profiles && container.value !== ctrl.selectedProfile.name)) {
|
||||
|
||||
ctrl.formFields = [];
|
||||
|
||||
let currentFactory = ctrl.factories.length > 1 ? ctrl.selectedFactory : ctrl.factories[0];
|
||||
|
||||
ctrl.formFields.push({
|
||||
label: 'Factory',
|
||||
name: 'factoryId',
|
||||
type: 'text',
|
||||
description: currentFactory.description,
|
||||
value: currentFactory.displayName,
|
||||
originalValue: currentFactory.name,
|
||||
readOnly: true,
|
||||
required: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? false : true,
|
||||
group: 'general'
|
||||
});
|
||||
|
||||
let mbeanName = ctrl.factories.length > 1 ? ctrl.selectedFactory.mbeanName : ctrl.factories[0].mbeanName;
|
||||
|
||||
entaxyService.getFields(mbeanName)
|
||||
.then((response) => {
|
||||
|
||||
let groups = new Set();
|
||||
groups.add('general');
|
||||
|
||||
_.forEach(JSON.parse(response), (field) => {
|
||||
|
||||
let objectId = undefined;
|
||||
if (ctrl.mode !== Entaxy.MODAL_MODES.ADD) {
|
||||
objectId = ctrl.resolve.info['objectId'];
|
||||
}
|
||||
let profileName = ctrl.selectedProfile ?
|
||||
ctrl.selectedProfile.name : ctrl.resolve.parentName;
|
||||
let formField = entaxyService.makeFormField(field, objectId, ctrl.properties,
|
||||
ctrl.configurableOnly, ctrl.mode, ctrl.resolve.itemMbeanName, profileName);
|
||||
if (formField) {
|
||||
ctrl.formFields.push(formField);
|
||||
groups.add(formField.group);
|
||||
}
|
||||
});
|
||||
|
||||
if (ctrl.mode !== Entaxy.MODAL_MODES.VIEW) {
|
||||
processDependencies();
|
||||
}
|
||||
|
||||
ctrl.groups = Array.from(groups).map((group) => { return { name: group, displayName: group }; });
|
||||
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = false;
|
||||
ctrl.step3 = true;
|
||||
});
|
||||
} else {
|
||||
ctrl.step1 = false;
|
||||
ctrl.step2 = false;
|
||||
ctrl.step3 = true;
|
||||
}
|
||||
}
|
||||
|
||||
let watchers = [];
|
||||
function processDependencies() {
|
||||
let dependentFormFields = entaxyService.getDependentFormFields(ctrl.formFields, ctrl.configurableOnly);
|
||||
ctrl.definingFormFields = entaxyService.getDefiningFormFields(dependentFormFields, ctrl.formFields);
|
||||
|
||||
for (let i = 0; i < ctrl.definingFormFields.length; i++) {
|
||||
if (ctrl.definingFormFields[i].value) {
|
||||
let initialRunDependentFormFields = ctrl.mode === Entaxy.MODAL_MODES.ADD ?
|
||||
dependentFormFields :
|
||||
dependentFormFields.filter(field => (field.typeInfo && field.typeInfo.type === 'list'));
|
||||
entaxyService.processDependencies(initialRunDependentFormFields,
|
||||
ctrl.definingFormFields,
|
||||
ctrl.definingFormFields[i].name,
|
||||
ctrl.definingFormFields[i].value,
|
||||
undefined);
|
||||
}
|
||||
watchers.push(
|
||||
$scope.$watch('$ctrl.definingFormFields[' + i + '].value', function(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
entaxyService.processDependencies(dependentFormFields,
|
||||
ctrl.definingFormFields,
|
||||
ctrl.definingFormFields[i].name,
|
||||
newValue,
|
||||
oldValue);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.back = function() {
|
||||
if (ctrl.step2 === true) {
|
||||
ctrl.step1 = true;
|
||||
ctrl.step2 = false;
|
||||
} else if (ctrl.step3 === true) {
|
||||
ctrl.errors = undefined;
|
||||
clearWatchers();
|
||||
ctrl.step2 = true;
|
||||
ctrl.step3 = false;
|
||||
}
|
||||
}
|
||||
|
||||
function clearWatchers() {
|
||||
if (watchers && watchers.length > 0) {
|
||||
watchers.forEach(watcher => {
|
||||
watcher();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.changeProfileSelection = function(item, isDblClicked) {
|
||||
ctrl.selectedProfile = item;
|
||||
if (isDblClicked) {
|
||||
ctrl.next();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.changeFactorySelection = function(item, isDblClicked) {
|
||||
ctrl.selectedFactory = item;
|
||||
if (isDblClicked) {
|
||||
ctrl.next();
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.shouldShowChangesNote = function () {
|
||||
return ctrl.mode !== Entaxy.MODAL_MODES.ADD &&
|
||||
(ctrl.isFormDirty || ctrl.hasChangedPrivateObjects || ctrl.hasChangesFromDiagram);
|
||||
}
|
||||
|
||||
ctrl.save = function() {
|
||||
|
||||
if (ctrl.mode === Entaxy.MODAL_MODES.VIEW) {
|
||||
ctrl.cancel();
|
||||
}
|
||||
|
||||
let isConfirmationNeeded = ctrl.mode === Entaxy.MODAL_MODES.EDIT &&
|
||||
!ctrl.isFormDirty && !ctrl.hasChangedPrivateObjects && !ctrl.hasChangesFromDiagram;
|
||||
entaxyService.requestConfirmationForSavingIfNeededAndProceed(isConfirmationNeeded, save);
|
||||
}
|
||||
|
||||
function save () {
|
||||
let selectedFactory = ctrl.selectedFactory ? ctrl.selectedFactory : ctrl.factories[0];
|
||||
let profileMBeanName = ctrl.selectedProfile ? ctrl.selectedProfile.mbeanName : undefined;
|
||||
|
||||
entaxyService.validateFields(ctrl.formFields, selectedFactory, ctrl.itemType,
|
||||
profileMBeanName, ctrl.resolve.checkUniquenessParentFields)
|
||||
.then(errors => {
|
||||
ctrl.errors = errors;
|
||||
|
||||
if (Object.keys(ctrl.errors).length === 0) {
|
||||
if (ctrl.resolve.returnFormFields) {
|
||||
ctrl.modalInstance.close(Entaxy.deepCopy(ctrl.formFields));
|
||||
} else {
|
||||
let args = entaxyService.getArguments(ctrl.formFields, ctrl.factories);
|
||||
args.configProperties = ctrl.properties;
|
||||
args.configurableOnly = ctrl.configurableOnly;
|
||||
ctrl.modalInstance.close(args);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
entaxyModalController.$inject = ['$scope', 'entaxyService', 'entaxyPrivateObjectsCacheService',
|
||||
'entaxyProfileDiagramService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,86 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyOperationTableRequestModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container simple-modal-content operation-table-request-modal">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{$ctrl.message}}</p>
|
||||
<div class="operation-affected-table-container">
|
||||
<entaxy-operation-affected-table items="$ctrl.affectedObjects"></entaxy-operation-affected-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="$ctrl.apply('current')">Apply only to current</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="$ctrl.apply('all')">Apply to all</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyOperationTableRequestModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyOperationTableRequestModalController($uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.operationType = ctrl.resolve.operationType.toUpperCase();
|
||||
|
||||
ctrl.modalTitle = 'Confirm operation ' + ctrl.operationType;
|
||||
ctrl.message = 'To execute operation ' + ctrl.operationType + ' on '
|
||||
+ ctrl.resolve.objectDisplayName + ' [' + ctrl.resolve.objectFullId + '] '
|
||||
+ 'corresponding operations should be applied to the following affected objects:';
|
||||
|
||||
ctrl.affectedObjects = ctrl.resolve.affectedObjects;
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.apply = function (flag) {
|
||||
ctrl.modalInstance.close(flag);
|
||||
}
|
||||
|
||||
}
|
||||
entaxyOperationTableRequestModalController.$inject = ['$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,229 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyResourceViewerModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body-without-header">
|
||||
<div class="modal-resources-viewer-container">
|
||||
<div class="modal-resources-viewer-header-container">
|
||||
<entaxy-crumbs root-crumb="$ctrl.protocol" crumbs="$ctrl.crumbs"></entaxy-crumbs>
|
||||
<button type="button" data-toggle="tooltip" title="Create folder"
|
||||
ng-click="$ctrl.addFolder()" ng-if="$ctrl.enableFolderAdding">
|
||||
<span class="pficon pficon-add-circle-o"></span>
|
||||
</button>
|
||||
</div>
|
||||
<entaxy-file-panel items="$ctrl.items" selected-item="$ctrl.selectedItem" view="$ctrl.view"
|
||||
change-selection-fn="$ctrl.changeSelection" open-fn="$ctrl.open"></entaxy-file-panel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Select</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyResourceViewerModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyResourceViewerModalController($uibModal, $scope, entaxyResourcesService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.modalTitle = 'Select Resources';
|
||||
|
||||
ctrl.view = 'tiles';
|
||||
ctrl.protocol = ctrl.resolve.config.resourceProvider;
|
||||
|
||||
let provider = entaxyResourcesService.getProviderMbean(ctrl.protocol);
|
||||
ctrl.providerMBeanName = provider.objectName;
|
||||
|
||||
ctrl.filter = ctrl.resolve.config.filter;
|
||||
|
||||
ctrl.enableFolderSelection = ctrl.resolve.config.target === 'folder' ? true : false;
|
||||
ctrl.enableFolderAdding = ctrl.resolve.config.enableFolderAdding;
|
||||
|
||||
let location = ctrl.resolve.location;
|
||||
ctrl.useShortUrl = ctrl.resolve.config.useShortUrl;
|
||||
|
||||
if (location && location.includes(':')) {
|
||||
let path = ctrl.useShortUrl ? location.split(':')[1] : location.slice(18);
|
||||
if (path.length > 0) {
|
||||
let splitPath = path.split('/');
|
||||
if (!ctrl.useShortUrl) {
|
||||
splitPath.shift();
|
||||
}
|
||||
if (!ctrl.enableFolderSelection) {
|
||||
splitPath.pop();
|
||||
}
|
||||
// todo else check if the last item in path is folder or not
|
||||
ctrl.crumbs = splitPath;
|
||||
} else {
|
||||
ctrl.crumbs = [];
|
||||
}
|
||||
} else {
|
||||
ctrl.crumbs = [];
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watchCollection('$ctrl.crumbs', function(newValue, oldValue) {
|
||||
ctrl.selectedItem = null;
|
||||
updateItems();
|
||||
})
|
||||
|
||||
ctrl.changeSelection = function (item) {
|
||||
if (!item.error) {
|
||||
ctrl.selectedItem = item;
|
||||
} else {
|
||||
Entaxy.notificationError('Cannot select the resource containing an error');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.open = function (item) {
|
||||
if (item.isFolder === true) {
|
||||
ctrl.crumbs.push(item.name);
|
||||
} else {
|
||||
ctrl.changeSelection(item);
|
||||
if (!item.error) {
|
||||
ctrl.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let clientFolders = [];
|
||||
|
||||
ctrl.addFolder = function () {
|
||||
entaxyResourcesService.addFolder(ctrl.items, clientFolders, ctrl.crumbs);
|
||||
}
|
||||
|
||||
function updateItems() {
|
||||
let path = entaxyResourcesService.getPath(ctrl.crumbs);
|
||||
|
||||
getItems(path).then(originItems => {
|
||||
|
||||
if (ctrl.enableFolderAdding && ctrl.crumbs.length > 0 &&
|
||||
originItems.length == 0 && clientFolders.length == 0) {
|
||||
populateAddedFoldersFromLocation(ctrl.crumbs);
|
||||
}
|
||||
|
||||
let items = originItems
|
||||
.concat(entaxyResourcesService.getClientFoldersToAdd(clientFolders, originItems, ctrl.crumbs));
|
||||
|
||||
if (ctrl.filter === 'foldersOnly') {
|
||||
items = items.filter(item => item.isFolder);
|
||||
} else if (Array.isArray(ctrl.filter) && ctrl.filter.length > 0) {
|
||||
items = items.filter(item => {
|
||||
let match = false;
|
||||
if (item.isFolder) {
|
||||
return true;
|
||||
}
|
||||
ctrl.filter.forEach(filter => {
|
||||
if (filter.startsWith('*') && item.name.endsWith(filter.substring(1, filter.length))) {
|
||||
match = true;
|
||||
}
|
||||
});
|
||||
return match;
|
||||
});
|
||||
} else if (ctrl.filter && ctrl.filter.startsWith('*')) {
|
||||
items = items.filter(item => item.isFolder || item.name.endsWith(ctrl.filter.substring(1, ctrl.filter.length)));
|
||||
}
|
||||
ctrl.items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
|
||||
})
|
||||
}
|
||||
|
||||
function populateAddedFoldersFromLocation(originCrumbs) {
|
||||
let crumbs = Entaxy.deepCopy(originCrumbs);
|
||||
|
||||
if (crumbs.length > 0) {
|
||||
let lastFolderName = crumbs.pop();
|
||||
let path = entaxyResourcesService.getPath(crumbs);
|
||||
|
||||
getItems(path).then(result => {
|
||||
let items = JSON.parse(result);
|
||||
|
||||
if (items.length == 0) {
|
||||
let addedFolder = entaxyResourcesService.createFolder(lastFolderName, crumbs);
|
||||
clientFolders.push(addedFolder);
|
||||
populateAddedFoldersFromLocation(crumbs);
|
||||
} else {
|
||||
if (!items.map(item => item.name).includes(lastFolderName)) {
|
||||
let addedFolder = entaxyResourcesService.createFolder(lastFolderName, crumbs);
|
||||
clientFolders.push(addedFolder);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getItems(path) {
|
||||
return entaxyResourcesService.getResourcesInfo(ctrl.providerMBeanName, path);
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.save = function() {
|
||||
if (ctrl.selectedItem) {
|
||||
if (!ctrl.selectedItem.isFolder || ctrl.enableFolderSelection) {
|
||||
let path = entaxyResourcesService.getPath(ctrl.crumbs);
|
||||
let folderLocation = getFolderLocation(path);
|
||||
let separator = path.length > 0 ? '/' : '';
|
||||
let location = folderLocation + separator + ctrl.selectedItem.name;
|
||||
ctrl.modalInstance.close(location);
|
||||
}
|
||||
} else {
|
||||
if (ctrl.enableFolderSelection) {
|
||||
let path = entaxyResourcesService.getPath(ctrl.crumbs);
|
||||
let folderLocation = getFolderLocation(path);
|
||||
ctrl.modalInstance.close(folderLocation);
|
||||
} else {
|
||||
Entaxy.notificationError('There is no selected resource');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getFolderLocation(path) {
|
||||
return ctrl.useShortUrl ? ctrl.protocol + ':' + path : 'entaxy-resource://' + ctrl.protocol + '/' + path;
|
||||
}
|
||||
}
|
||||
entaxyResourceViewerModalController.$inject = ['$uibModal', '$scope', 'entaxyResourcesService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxySimpleResourceNameInputModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-simple-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body-small">
|
||||
<div class="form-group" ng-class="{'has-error': $ctrl.error}">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control" ng-model="$ctrl.name" ng-if="!$ctrl.extension">
|
||||
<entaxy-input-with-extension model="$ctrl.name" ng-if="$ctrl.extension"
|
||||
model-without-extension="$ctrl.nameWithoutExtension" extension="$ctrl.extension">
|
||||
</entaxy-input-with-extension>
|
||||
<span class="help-block" ng-show="$ctrl.error">{{$ctrl.error}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxySimpleResourceNameInputModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxySimpleResourceNameInputModalController($uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.title = ctrl.resolve.title;
|
||||
ctrl.type = ctrl.resolve.type ? ctrl.resolve.type : 'Resource';
|
||||
ctrl.name = ctrl.resolve.name;
|
||||
if (ctrl.name && ctrl.type === 'Resource') {
|
||||
let dotIndex = ctrl.name.lastIndexOf('.');
|
||||
if (dotIndex > -1) {
|
||||
ctrl.nameWithoutExtension = ctrl.name.slice(0, dotIndex);
|
||||
ctrl.extension = ctrl.name.slice(dotIndex);
|
||||
}
|
||||
}
|
||||
ctrl.names = ctrl.resolve.names;
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.save = function() {
|
||||
ctrl.error = validate();
|
||||
if (!ctrl.error) {
|
||||
ctrl.modalInstance.close(ctrl.name);
|
||||
}
|
||||
}
|
||||
|
||||
function validate() {
|
||||
let error;
|
||||
if (isEmpty(ctrl.name) || (ctrl.extension && isEmpty(ctrl.nameWithoutExtension))) {
|
||||
return ctrl.type + ' name must not be empty';
|
||||
}
|
||||
['/', '\\', ':', '*', '?', '<', '>', '|'].forEach((symbol) => {
|
||||
if (ctrl.name.indexOf(symbol) >= 0) {
|
||||
error = ctrl.type + ' name must not include symbols /\\:*?<>|';
|
||||
}
|
||||
});
|
||||
ctrl.names.forEach((name) => {
|
||||
if (name === ctrl.name) {
|
||||
error = ctrl.type + ' with this name already exists';
|
||||
}
|
||||
});
|
||||
return error;
|
||||
}
|
||||
|
||||
function isEmpty(value) {
|
||||
return !value || value.length == 0 || value.trim().length == 0;
|
||||
}
|
||||
}
|
||||
entaxySimpleResourceNameInputModalController.$inject = ['$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyXmlModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body-without-header">
|
||||
<div class="xml-editor-container">
|
||||
<entaxy-xml-editor class="xml-editor" source-doc="$ctrl.xml" read-only="$ctrl.readOnly"></entaxy-xml-editor>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save($ctrl.formFields)">{{$ctrl.btnTitle}}</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyXmlModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyXmlModalController($uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.mode = ctrl.resolve.mode;
|
||||
ctrl.modalTitle = ctrl.mode + ' XML';
|
||||
ctrl.btnTitle = ctrl.resolve.defineButtonTitleByMode ? Entaxy.getButtonTitleByMode(ctrl.mode) : 'Ok';
|
||||
ctrl.readOnly = ctrl.mode === Entaxy.MODAL_MODES.VIEW;
|
||||
ctrl.xml = ctrl.resolve.xml;
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.save = function() {
|
||||
if (ctrl.readOnly) {
|
||||
ctrl.cancel();
|
||||
} else {
|
||||
if ((ctrl.xml && angular.isString(ctrl.xml) && ctrl.xml.trim().length > 0) ||
|
||||
!angular.isString(ctrl.xml)) {
|
||||
ctrl.modalInstance.close(ctrl.xml);
|
||||
} else {
|
||||
Entaxy.notificationError('Value should not be empty');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entaxyXmlModalController.$inject = ['$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,174 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyConnectorsWithFlow', {
|
||||
bindings: {
|
||||
direction: '@',
|
||||
connectors: '<',
|
||||
profileName: '<',
|
||||
editCustomizationPointFn: '<',
|
||||
editProfilePropertiesFn: '<',
|
||||
editPropertiesFn: '<',
|
||||
saveConnectorFn: '<',
|
||||
updateFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="connectors-group-container">
|
||||
<span class="connectors-group-title">{{$ctrl.connectorsGroupTitle}}</span>
|
||||
<div class="connectors-with-flow-container">
|
||||
<div class="connectors-container">
|
||||
<div class="connector-block" ng-repeat="connector in $ctrl.connectors"
|
||||
ng-class="{'has-changes': connector.isChanged}"
|
||||
ng-click="$ctrl.editConnectorProperties(connector, $event)">
|
||||
<div class="connector-info">
|
||||
<div class="connector-title-container">
|
||||
<span class="profile-diagram-support-span" ng-if="connector.isChanged"></span>
|
||||
<span class="bold connector-title" data-toggle="tooltip" title="{{connector.displayName}}">
|
||||
{{connector.displayName}}
|
||||
</span>
|
||||
<span class="pficon pficon-save" ng-click="$ctrl.saveConnector(connector, $event)"
|
||||
data-toggle="tooltip" title="Save connector changes" ng-if="connector.isChanged"></span>
|
||||
</div>
|
||||
<span class="connector-classifier">{{connector.classifier}}</span>
|
||||
</div>
|
||||
<div id="{{connector.name}}_{{customizationPoint}}" class="customization-point-block"
|
||||
ng-repeat="customizationPoint in $ctrl.connectorCustomizationPoints"
|
||||
ng-click="$ctrl.editConnectorCustomizationPoint(connector, customizationPoint, $event)">
|
||||
{{customizationPoint}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="{{$ctrl.direction}}-flow-block" class="flow-block"
|
||||
ng-click="$ctrl.editProfileProperties($ctrl.direction + '-flow', $event)">
|
||||
<span>{{$ctrl.flowName}}</span>
|
||||
<div class="out-flow-customization-points-container" ng-if="$ctrl.isDirectionOut">
|
||||
<div id="{{$ctrl.direction}}-flow_connector-selector"
|
||||
class="customization-point-block connector-selector"
|
||||
ng-click="$ctrl.editFlowCustomizationPoint('connector-selector', $event)"
|
||||
data-toggle="tooltip" title="connector-selector">
|
||||
<span class="connector-selector-icon"></span>
|
||||
</div>
|
||||
<div id="{{$ctrl.direction}}-flow_pre-route"
|
||||
class="customization-point-block pre-route"
|
||||
ng-click="$ctrl.editFlowCustomizationPoint('pre-route', $event)">
|
||||
pre-route
|
||||
</div>
|
||||
</div>
|
||||
<div id="{{$ctrl.direction}}-flow_{{customizationPoint}}" class="customization-point-block"
|
||||
ng-repeat="customizationPoint in $ctrl.flowCustomizationPoints"
|
||||
ng-click="$ctrl.editFlowCustomizationPoint(customizationPoint, $event)">
|
||||
{{customizationPoint}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyConnectorsWithFlowController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyConnectorsWithFlowController(workspace) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
if (ctrl.direction) {
|
||||
let isDirectionIn = ctrl.direction === 'in';
|
||||
ctrl.isDirectionOut = !isDirectionIn;
|
||||
ctrl.connectorsGroupTitle = '--- ' + ctrl.direction.toUpperCase() + ' ---';
|
||||
ctrl.flowName = ctrl.direction.toUpperCase() + '-FLOW';
|
||||
ctrl.connectorCustomizationPoints = isDirectionIn ? ['pre-route', 'response'] : ['pre-output', 'postprocess'];
|
||||
ctrl.flowCustomizationPoints = isDirectionIn ? ['pre-route', 'response'] : ['postprocess'];
|
||||
} else {
|
||||
Entaxy.log.error('Connectors group direction is not defined');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.editConnectorProperties = function (connector, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
ctrl.editPropertiesFn(connector, Entaxy.RUNTIME_TYPE.CONNECTOR, 'Connector');
|
||||
}
|
||||
|
||||
ctrl.editConnectorCustomizationPoint = function (connector, customizationPoint, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
let propertyName = getPropertyNameForConnectorCustomizationPoint(customizationPoint);
|
||||
|
||||
ctrl.editCustomizationPointFn(connector.mbeanName, propertyName, connector);
|
||||
}
|
||||
|
||||
ctrl.editProfileProperties = function (groupName, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
ctrl.editProfilePropertiesFn(groupName);
|
||||
}
|
||||
|
||||
ctrl.editFlowCustomizationPoint = function (customizationPoint, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
let propertyName = getPropertyNameForFlowCustomizationPoint(customizationPoint);
|
||||
|
||||
ctrl.editCustomizationPointFn(selectedMbeanName, propertyName);
|
||||
}
|
||||
|
||||
function getPropertyNameForConnectorCustomizationPoint(customizationPointName) {
|
||||
switch (customizationPointName) {
|
||||
case 'pre-route':
|
||||
case 'pre-output':
|
||||
return customizationPointName;
|
||||
case 'response':
|
||||
case 'postprocess':
|
||||
return 'responseRoute';
|
||||
};
|
||||
}
|
||||
|
||||
function getPropertyNameForFlowCustomizationPoint(customizationPointName) {
|
||||
switch (customizationPointName) {
|
||||
case 'pre-route':
|
||||
return ctrl.direction + '-flow-' + customizationPointName;
|
||||
case 'response':
|
||||
case 'postprocess':
|
||||
return ctrl.direction + '-flow-response';
|
||||
case 'connector-selector':
|
||||
return customizationPointName;
|
||||
};
|
||||
}
|
||||
|
||||
ctrl.saveConnector = function (connector, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
ctrl.saveConnectorFn(connector.mbeanName, true, false);
|
||||
}
|
||||
}
|
||||
entaxyConnectorsWithFlowController.$inject = ['workspace'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,699 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyProfileDiagramExternalSystemPoints', {
|
||||
bindings: {
|
||||
connectors: '<',
|
||||
type: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div ng-repeat="connector in $ctrl.connectors" ng-if="$ctrl.connectors && $ctrl.connectors.length > 0"
|
||||
id="{{$ctrl.type}}-{{connector.name}}-block" class="external-system-point-block">
|
||||
<span>{{$ctrl.type}}</span>
|
||||
<div>
|
||||
<span class="left-bracket"></span>
|
||||
<span class="connector-info"
|
||||
data-toggle="tooltip" title="{{connector.protocol}}">{{connector.protocol}}</span>
|
||||
<span class="right-bracket"></span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
.component('entaxyProfileDiagram', {
|
||||
template:
|
||||
`
|
||||
<div id="leader-lines-container" class="profile-diagram-with-palette-container">
|
||||
<div class="profile-diagram-container">
|
||||
|
||||
<div class="blocks-container">
|
||||
<entaxy-profile-diagram-external-system-points connectors="$ctrl.inConnectors" type="source">
|
||||
</entaxy-profile-diagram-external-system-points>
|
||||
<entaxy-profile-diagram-external-system-points connectors="$ctrl.outConnectors" type="target">
|
||||
</entaxy-profile-diagram-external-system-points>
|
||||
</div>
|
||||
|
||||
<div droppable handle-drop-fn="$ctrl.handleDropFn(droppedElementId)" class="profile-block"
|
||||
ng-class="{'has-changes': $ctrl.isProfileChanged}"
|
||||
ng-click="$ctrl.editProfileProperties('general')">
|
||||
<div class="profile-title-container">
|
||||
<span class="profile-diagram-support-span" ng-if="$ctrl.isProfileChanged"></span>
|
||||
<span class="profile-title">{{$ctrl.profileTitle}}</span>
|
||||
<span class="pficon pficon-save" ng-click="$ctrl.saveProfile($event)"
|
||||
data-toggle="tooltip" title="Save profile changes" ng-if="$ctrl.isProfileChanged"></span>
|
||||
</div>
|
||||
|
||||
<entaxy-connectors-with-flow direction="in" connectors="$ctrl.inConnectors"
|
||||
profile-name="$ctrl.profileName" edit-customization-point-fn="$ctrl.editCustomizationPoint"
|
||||
ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0" update-fn="$ctrl.update"
|
||||
edit-profile-properties-fn="$ctrl.editProfileProperties"
|
||||
edit-properties-fn="$ctrl.editProperties" save-connector-fn="$ctrl.save">
|
||||
</entaxy-connectors-with-flow>
|
||||
|
||||
<entaxy-connectors-with-flow direction="out" connectors="$ctrl.outConnectors"
|
||||
profile-name="$ctrl.profileName" edit-customization-point-fn="$ctrl.editCustomizationPoint"
|
||||
ng-if="$ctrl.outConnectors && $ctrl.outConnectors.length > 0" update-fn="$ctrl.update"
|
||||
edit-profile-properties-fn="$ctrl.editProfileProperties"
|
||||
edit-properties-fn="$ctrl.editProperties" save-connector-fn="$ctrl.save">
|
||||
</entaxy-connectors-with-flow>
|
||||
</div>
|
||||
|
||||
<div class="blocks-container">
|
||||
<div id="integrations-in-block" class="integrations-block"
|
||||
ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
|
||||
<span>integrations</span>
|
||||
</div>
|
||||
<div id="default-route-block" class="default-route-block"
|
||||
ng-class="{'has-changes': $ctrl.isDefaultRouteChanged}"
|
||||
ng-click="$ctrl.editDefaultRouteProperties()"
|
||||
ng-if="$ctrl.inConnectors && $ctrl.inConnectors.length > 0">
|
||||
<div class="default-route-title-container">
|
||||
<span class="default-route-title">default-route</span>
|
||||
<span class="pficon pficon-save" ng-click="$ctrl.saveDefaultRoute($event)"
|
||||
data-toggle="tooltip" title="Save default route changes"
|
||||
ng-if="$ctrl.isDefaultRouteChanged"></span>
|
||||
</div>
|
||||
<div class="customization-point-block"
|
||||
ng-click="$ctrl.editDefaultRouteCustomizationPoint($event)">
|
||||
route
|
||||
</div>
|
||||
</div>
|
||||
<div id="integrations-out-block" class="integrations-block"
|
||||
ng-if="$ctrl.outConnectors && $ctrl.outConnectors.length > 0">
|
||||
<span>integrations</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<entaxy-profile-diagram-palette></entaxy-profile-diagram-palette>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyProfileDiagramController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyProfileDiagramController($scope, workspace, jolokia, $location, $q,
|
||||
entaxyService, entaxyProfileDiagramService, entaxyAttributesCacheService,
|
||||
entaxyPrivateObjectsCacheService, $uibModal, $route, $cookies) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMBean = workspace.getSelectedMBean();
|
||||
let defaultRouteMbean = selectedMBean.findDescendant(child =>
|
||||
child.objectName && child.objectName.endsWith('route=default'));
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
|
||||
ctrl.profileName = jolokia.getAttribute(selectedMBean.objectName, 'Name')
|
||||
ctrl.profileTitle = 'Profile: ' + ctrl.profileName;
|
||||
ctrl.isProfileChanged = entaxyProfileDiagramService.isProfileChanged();
|
||||
ctrl.isDefaultRouteChanged = entaxyProfileDiagramService.isDefaultRouteChanged();
|
||||
|
||||
populateConnectors();
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
let contentElement = document.getElementsByClassName("contents")[0];
|
||||
contentElement.style.setProperty("padding", "0", "important");
|
||||
}, 10);
|
||||
|
||||
function populateConnectors() {
|
||||
let inConnectors = [];
|
||||
let outConnectors = [];
|
||||
|
||||
if (selectedMBean && selectedMBean.isFolder) {
|
||||
entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, Entaxy.RUNTIME_TYPE.CONNECTOR)
|
||||
.then((mbeans) => {
|
||||
mbeans.forEach((mbean) => {
|
||||
let direction = mbean.attributes.Direction;
|
||||
let connectorMbeanName = mbean.mbean.objectName;
|
||||
let isConnectorChanged = entaxyProfileDiagramService.isConnectorChanged(connectorMbeanName);
|
||||
let connector = {
|
||||
name: mbean.attributes.Name,
|
||||
displayName: mbean.attributes.DisplayName,
|
||||
classifier: mbean.attributes.Classifier,
|
||||
protocol: mbean.attributes.Protocol,
|
||||
mbeanName: connectorMbeanName,
|
||||
isChanged: isConnectorChanged
|
||||
};
|
||||
if (direction === 'in') {
|
||||
inConnectors.push(connector);
|
||||
} else if (direction === 'out') {
|
||||
outConnectors.push(connector);
|
||||
}
|
||||
if (isConnectorChanged) {
|
||||
entaxyProfileDiagramService.getChanges(connectorMbeanName).connector = connector;
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.inConnectors = inConnectors.sort(Entaxy.compareBy('name'));
|
||||
ctrl.outConnectors = outConnectors.sort(Entaxy.compareBy('name'));
|
||||
|
||||
setMarginForAdditionalBlocks();
|
||||
if (ctrl.inConnectors.length > 0) {
|
||||
drawLinesForInDirectedConnectors();
|
||||
}
|
||||
if (ctrl.outConnectors.length > 0) {
|
||||
drawLinesForOutDirectedConnectors();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.handleDropFn = function (factoryName) {
|
||||
|
||||
let factory = entaxyService.getFactoryByTitle(factoryName);
|
||||
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
let parentName = jolokia.getAttribute(selectedMbeanName, 'Name');
|
||||
|
||||
let resolve = {
|
||||
mode: () => Entaxy.MODAL_MODES.ADD,
|
||||
itemType: () => 'Connector',
|
||||
parentName: () => parentName,
|
||||
factories: () => [ factory ]
|
||||
};
|
||||
|
||||
entaxyService.openModalAndProcessResults(resolve, false, null, () => ctrl.connectorAdded = true);
|
||||
}
|
||||
|
||||
// sets top margin for source, target, default-route and integration blocks
|
||||
function setMarginForAdditionalBlocks() {
|
||||
setTimeout(function () {
|
||||
let sourceBlocksOccupiedHeight = 0;
|
||||
let defaultRouteBlockMarginPlusHeight = 0;
|
||||
let padding = 10;
|
||||
if (ctrl.inConnectors && ctrl.inConnectors.length > 0) {
|
||||
let integrationsInBlock = document.getElementById("integrations-in-block");
|
||||
let inFlowBlock = document.getElementById("in-flow-block");
|
||||
let inFlowPreRouteBlock = document.getElementById("in-flow_pre-route");
|
||||
let defaultRouteBlock = document.getElementById("default-route-block");
|
||||
|
||||
let integrationsInBlockHeight = integrationsInBlock.offsetHeight;
|
||||
|
||||
let integrationsInBlockMarginTop = inFlowBlock.offsetTop -
|
||||
integrationsInBlockHeight - padding;
|
||||
let defaultRouteBlockMarginTop = inFlowPreRouteBlock.offsetTop -
|
||||
integrationsInBlockMarginTop - integrationsInBlockHeight - padding;
|
||||
|
||||
integrationsInBlock.style.marginTop = integrationsInBlockMarginTop + 'px';
|
||||
defaultRouteBlock.style.marginTop = defaultRouteBlockMarginTop + 'px';
|
||||
defaultRouteBlockMarginPlusHeight = integrationsInBlockMarginTop + integrationsInBlockHeight +
|
||||
defaultRouteBlockMarginTop + defaultRouteBlock.offsetHeight;
|
||||
|
||||
sourceBlocksOccupiedHeight =
|
||||
setMarginForSourceOrTargetBlocks(ctrl.inConnectors, true, sourceBlocksOccupiedHeight, padding);
|
||||
}
|
||||
if (ctrl.outConnectors && ctrl.outConnectors.length > 0) {
|
||||
let outFlowPreRouteBlock = document.getElementById("out-flow_pre-route");
|
||||
let integrationsBlock = document.getElementById("integrations-out-block");
|
||||
let integrationsBlockMarginTop = outFlowPreRouteBlock.offsetTop -
|
||||
defaultRouteBlockMarginPlusHeight - padding;
|
||||
integrationsBlock.style.marginTop = integrationsBlockMarginTop + 'px';
|
||||
|
||||
setMarginForSourceOrTargetBlocks(ctrl.outConnectors, false, sourceBlocksOccupiedHeight, padding);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function setMarginForSourceOrTargetBlocks(connectors, isSource, previousBlocksOccupiedHeight, padding) {
|
||||
connectors.forEach(connector => {
|
||||
let manageableBlock = isSource ?
|
||||
document.getElementById("source-" + connector.name + "-block") :
|
||||
document.getElementById("target-" + connector.name + "-block");
|
||||
let connectorCustomizationPointBlock = isSource ?
|
||||
document.getElementById(connector.name + "_pre-route") :
|
||||
document.getElementById(connector.name + "_pre-output");
|
||||
let manageableBlockMarginTop = connectorCustomizationPointBlock.offsetTop -
|
||||
previousBlocksOccupiedHeight - padding;
|
||||
manageableBlock.style.marginTop = manageableBlockMarginTop + 'px';
|
||||
previousBlocksOccupiedHeight += manageableBlockMarginTop + manageableBlock.offsetHeight;
|
||||
});
|
||||
return previousBlocksOccupiedHeight;
|
||||
}
|
||||
|
||||
let lines = [];
|
||||
|
||||
// draws lines for in-directed connector block
|
||||
function drawLinesForInDirectedConnectors () {
|
||||
setTimeout(function () {
|
||||
|
||||
if (ctrl.inConnectors) {
|
||||
ctrl.inConnectors.forEach((connector) => {
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('source-' + connector.name + '-block'),
|
||||
{x: '100%', y: 11}
|
||||
),
|
||||
document.getElementById(connector.name + '_pre-route'),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById(connector.name + '_pre-route'),
|
||||
document.getElementById('in-flow_pre-route'),
|
||||
{color: 'green', size: 2, path: 'grid', startSocketGravity: [10, 0]}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById(connector.name + '_response'),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('source-' + connector.name + '-block'),
|
||||
{x: '100%', y: 43}
|
||||
),
|
||||
{color: 'blue', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('in-flow_response'),
|
||||
{x: 0, y: '50%'}
|
||||
),
|
||||
document.getElementById(connector.name + '_response'),
|
||||
{color: 'blue', size: 2, path: 'grid', startSocketGravity: [-10, 0]}
|
||||
));
|
||||
});
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById('in-flow_pre-route'),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('default-route-block'),
|
||||
{x: 0, y: 11}
|
||||
),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('default-route-block'),
|
||||
{x: 0, y: 43}
|
||||
),
|
||||
document.getElementById('in-flow_response'),
|
||||
{color: 'blue', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('default-route-block'),
|
||||
{x: 32.5, y: 0}
|
||||
),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('integrations-in-block'),
|
||||
{x: 32.5, y: '100%'}
|
||||
),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('integrations-in-block'),
|
||||
{x: 64.5, y: '100%'}
|
||||
),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('default-route-block'),
|
||||
{x: 64.5, y: 0}
|
||||
),
|
||||
{color: 'blue', size: 2, path: 'straight'}
|
||||
));
|
||||
}
|
||||
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// draws lines for out-directed connector block
|
||||
function drawLinesForOutDirectedConnectors() {
|
||||
setTimeout(function () {
|
||||
|
||||
if (ctrl.outConnectors) {
|
||||
ctrl.outConnectors.forEach((connector) => {
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById(connector.name + '_pre-output'),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('target-' + connector.name + '-block'),
|
||||
{x: '100%', y: 11}
|
||||
),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById('out-flow_pre-route'),
|
||||
document.getElementById('out-flow_connector-selector'),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('out-flow_connector-selector'),
|
||||
{x: 0, y: '50%'}
|
||||
),
|
||||
document.getElementById(connector.name + '_pre-output'),
|
||||
{color: 'green', size: 2, path: 'grid', startSocketGravity: [-10, 0]}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('target-' + connector.name + '-block'),
|
||||
{x: '100%', y: 43}
|
||||
),
|
||||
document.getElementById(connector.name + '_postprocess'),
|
||||
{color: 'blue', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById(connector.name + '_postprocess'),
|
||||
document.getElementById('out-flow_postprocess'),
|
||||
{color: 'blue', size: 2, path: 'grid', startSocketGravity: [10, 0]}
|
||||
));
|
||||
})
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('integrations-out-block'),
|
||||
{x: 0, y: 11}
|
||||
),
|
||||
document.getElementById('out-flow_pre-route'),
|
||||
{color: 'green', size: 2, path: 'straight'}
|
||||
));
|
||||
|
||||
lines.push(new LeaderLine(
|
||||
document.getElementById('out-flow_postprocess'),
|
||||
LeaderLine.pointAnchor(
|
||||
document.getElementById('integrations-out-block'),
|
||||
{x: 0, y: 43}
|
||||
),
|
||||
{color: 'blue', size: 2, path: 'straight'}
|
||||
));
|
||||
}
|
||||
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// reposition of lines while container size is changed without changing window size
|
||||
let resizeObserver = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
if (entry.target.handleResize) {
|
||||
entry.target.handleResize(entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
document.querySelector('#leader-lines-container').handleResize = entry => {
|
||||
lines.forEach(line => line.position());
|
||||
}
|
||||
|
||||
resizeObserver.observe(document.querySelector('#leader-lines-container'));
|
||||
}, 10);
|
||||
|
||||
// reposition of lines on scroll event
|
||||
setTimeout(function () {
|
||||
let leaderLinesContainerElement = document.getElementById("leader-lines-container");
|
||||
|
||||
leaderLinesContainerElement.onscroll = (event) => {
|
||||
lines.forEach(line => line.position());
|
||||
};
|
||||
}, 10);
|
||||
|
||||
$scope.$on(Jmx.TreeEvent.Updated, () => {
|
||||
if (ctrl.connectorAdded) {
|
||||
$route.reload();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
lines.forEach(line => line.remove());
|
||||
resizeObserver.disconnect();
|
||||
$cookies.remove('profile-properties-group');
|
||||
});
|
||||
|
||||
ctrl.editProfileProperties = function (groupName) {
|
||||
$cookies.putObject('profile-properties-group', groupName);
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
let profile = createItem(selectedMbeanName);
|
||||
|
||||
ctrl.editProperties(profile, Entaxy.RUNTIME_TYPE.PROFILE, 'Profile');
|
||||
}
|
||||
|
||||
ctrl.editDefaultRouteProperties = function () {
|
||||
let defaultRouteMbeanName = defaultRouteMbean.objectName;
|
||||
let defaultRoute = createItem(defaultRouteMbeanName);
|
||||
|
||||
ctrl.editProperties(defaultRoute, Entaxy.RUNTIME_TYPE.DEFAULT_ROUTE, 'Default Route');
|
||||
}
|
||||
|
||||
function createItem(mbeanName) {
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(mbeanName);
|
||||
return {
|
||||
name: attributes.Name,
|
||||
mbeanName: mbeanName
|
||||
};
|
||||
}
|
||||
|
||||
ctrl.editProperties = function (item, runtimeType, itemType) {
|
||||
entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
|
||||
let isNonClustered = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED;
|
||||
if (isNonClustered) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.EDITING);
|
||||
}
|
||||
|
||||
let mode = isNonClustered ? Entaxy.MODAL_MODES.VIEW : Entaxy.MODAL_MODES.EDIT;
|
||||
item.isLocal = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL;
|
||||
let args = entaxyProfileDiagramService.hasChanges(item.mbeanName) ?
|
||||
entaxyProfileDiagramService.getArgs(item.mbeanName) : undefined;
|
||||
let properties = args ? args.fields.filter(field => field.name !== 'routes') : undefined;
|
||||
|
||||
entaxyService.openEditItemModalAndProcessResults(item, itemType, runtimeType, mode,
|
||||
properties, ctrl.update);
|
||||
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
|
||||
ctrl.editDefaultRouteCustomizationPoint = function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (defaultRouteMbean) {
|
||||
ctrl.editCustomizationPoint(defaultRouteMbean.objectName, 'routeContent');
|
||||
} else {
|
||||
Entaxy.notificationError('Default route is not found.');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.editCustomizationPoint = function (mbeanName, propertyName, connector) {
|
||||
if (entaxyProfileDiagramService.hasChanges(mbeanName)) {
|
||||
let changes = entaxyProfileDiagramService.getChanges(mbeanName);
|
||||
|
||||
processPropertyAndOpenXmlEditor(changes, propertyName, mbeanName, true);
|
||||
} else {
|
||||
entaxyService.readConfiguration(mbeanName)
|
||||
.then(objectInfo => {
|
||||
let args = entaxyService.getArgumentsFromConfig(objectInfo);
|
||||
let changes = entaxyProfileDiagramService.createChangesConfig(mbeanName, objectInfo.objectId,
|
||||
args, objectInfo.configurableOnly, connector);
|
||||
|
||||
processPropertyAndOpenXmlEditor(changes, propertyName, mbeanName);
|
||||
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
Entaxy.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function processPropertyAndOpenXmlEditor(changes, propertyName, mbeanName, isRoutesFieldResolved) {
|
||||
let args = changes.args;
|
||||
let property = args.fields.find(property => property.name === propertyName);
|
||||
|
||||
if (property.value) {
|
||||
if (isRoutesFieldResolved) {
|
||||
resolveConfirmationAndOpenXmlEditor(changes, property, propertyName, mbeanName);
|
||||
} else {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
let mbean = selectedMbean.objectName === mbeanName ?
|
||||
selectedMbean : selectedMbean.findDescendant(child => child.objectName === mbeanName);
|
||||
|
||||
entaxyService.resolveRoutesFieldValueAndAddNew(args, mbean)
|
||||
.then(() => {
|
||||
resolveConfirmationAndOpenXmlEditor(changes, property, propertyName, mbeanName);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Entaxy.notificationError('Content is not found');
|
||||
}
|
||||
}
|
||||
|
||||
function resolveConfirmationAndOpenXmlEditor(changes, property, propertyName, mbeanName) {
|
||||
entaxyService.readObjectClusterState(mbeanName).then(objectClusterState => {
|
||||
let isNonClustered = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED;
|
||||
if (isNonClustered) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.EDITING);
|
||||
}
|
||||
|
||||
if (changes.configurableOnly || isNonClustered) {
|
||||
getXmlAndOpenEditor(property, mbeanName, true, changes);
|
||||
} else {
|
||||
let args = changes.args;
|
||||
let factoryMbeanName = args.factoryId.mbeanName;
|
||||
entaxyService.getFields(factoryMbeanName).then(response => {
|
||||
let fields = JSON.parse(response);
|
||||
let currentField = fields.find(field => field.name === propertyName);
|
||||
const UI = '@UI';
|
||||
let managedByFieldName = currentField[UI] ? currentField[UI].managedBy : undefined;
|
||||
if (managedByFieldName) {
|
||||
let managingFieldProperty = args.fields
|
||||
.find(field => field.name === managedByFieldName);
|
||||
if (managingFieldProperty.value) {
|
||||
getXmlAndOpenEditor(property, mbeanName, changes.configurableOnly, changes);
|
||||
} else {
|
||||
let managingField = fields.find(field => field.name === managedByFieldName);
|
||||
let title = 'Confirm editing';
|
||||
let message = managingField.displayName + ' is currently disabled. ' +
|
||||
'Do you want to enable it and edit the ' + currentField.displayName + '?';
|
||||
|
||||
entaxyService.openConfirmationWindow(title, message).then(() => {
|
||||
managingFieldProperty.value = true;
|
||||
getXmlAndOpenEditor(property, mbeanName, changes.configurableOnly, changes);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
getXmlAndOpenEditor(property, mbeanName, changes.configurableOnly, changes);
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
|
||||
function getXmlAndOpenEditor(property, mbeanName, readOnly, changes) {
|
||||
entaxyService.getXmlFromConfigPropertyValue(property.value)
|
||||
.then(xml => openXmlEditor(xml, property, mbeanName, readOnly, changes));
|
||||
}
|
||||
|
||||
function openXmlEditor(originXml, property, mbeanName, readOnly, changes) {
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyXmlModal',
|
||||
resolve: {
|
||||
xml: () => originXml,
|
||||
mode: () => readOnly ? Entaxy.MODAL_MODES.VIEW : Entaxy.MODAL_MODES.EDIT
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(xml => {
|
||||
if (xml && xml.trim().length > 0) { // fixme
|
||||
property.value = Entaxy.stringToBase64(xml);
|
||||
if (!entaxyProfileDiagramService.hasChanges(mbeanName)) {
|
||||
entaxyProfileDiagramService.setChanges(mbeanName, changes);
|
||||
}
|
||||
if (entaxyProfileDiagramService.hasType(mbeanName, Entaxy.RUNTIME_TYPE.PROFILE)) {
|
||||
entaxyProfileDiagramService.setProfileChanged();
|
||||
ctrl.isProfileChanged = entaxyProfileDiagramService.isProfileChanged();
|
||||
} else if (entaxyProfileDiagramService.hasType(mbeanName, Entaxy.RUNTIME_TYPE.DEFAULT_ROUTE)) {
|
||||
entaxyProfileDiagramService.setDefaultRouteChanged();
|
||||
ctrl.isDefaultRouteChanged = entaxyProfileDiagramService.isDefaultRouteChanged();
|
||||
} else if (entaxyProfileDiagramService.hasType(mbeanName, Entaxy.RUNTIME_TYPE.CONNECTOR)) {
|
||||
entaxyProfileDiagramService.setConnectorChanged(mbeanName, true);
|
||||
}
|
||||
entaxyProfileDiagramService.setDirty();
|
||||
} else {
|
||||
Entaxy.notificationError('Value cannot be empty');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.saveProfile = function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
ctrl.save(selectedMBean.objectName, true, true);
|
||||
}
|
||||
|
||||
ctrl.saveDefaultRoute = function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
ctrl.save(defaultRouteMbean.objectName, false);
|
||||
}
|
||||
|
||||
ctrl.save = function (mbeanName, isConfirmationNeeded, isProfile) {
|
||||
if (entaxyPrivateObjectsCacheService.isChanged(mbeanName) && isConfirmationNeeded) {
|
||||
let title = 'Confirm Saving';
|
||||
let type = isProfile ? 'Profile' : 'Connector';
|
||||
let message = type + ' has unsaved changes of routes which will also be applied. ' +
|
||||
'Do you want to continue?';
|
||||
entaxyService.openConfirmationWindow(title, message).then(() => save(mbeanName));
|
||||
} else {
|
||||
save(mbeanName);
|
||||
}
|
||||
}
|
||||
|
||||
function save(mbeanName) {
|
||||
let args = entaxyProfileDiagramService.getArgs(mbeanName);
|
||||
entaxyService.resolveResourceRefFields(args.fields)
|
||||
.then(() => entaxyService.saveItem(args, false, ctrl.update));
|
||||
}
|
||||
|
||||
ctrl.update = function (properties, objectId) {
|
||||
entaxyProfileDiagramService.resetChanges(objectId);
|
||||
ctrl.isProfileChanged = entaxyProfileDiagramService.isProfileChanged();
|
||||
ctrl.isDefaultRouteChanged = entaxyProfileDiagramService.isDefaultRouteChanged();
|
||||
}
|
||||
|
||||
setTimeout( function () {
|
||||
ctrl.activeTabIndex = entaxyService.getActiveTabIndex();
|
||||
})
|
||||
|
||||
$scope.$on("$locationChangeStart", function(event) {
|
||||
if (entaxyProfileDiagramService.isDirty()) {
|
||||
if (!confirm(Entaxy.CONFIRMATION.UNSAVED_CHANGES)) {
|
||||
event.preventDefault();
|
||||
ctrl.isTreeOrTabSelectionUpdateNeeded = true;
|
||||
} else {
|
||||
entaxyProfileDiagramService.clear();
|
||||
}
|
||||
} else {
|
||||
entaxyProfileDiagramService.clear();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('$ctrl.isTreeOrTabSelectionUpdateNeeded', function (newValue) {
|
||||
if (newValue) {
|
||||
setTimeout(function () {
|
||||
entaxyService.updateTabSelection(ctrl.activeTabIndex);
|
||||
});
|
||||
Jmx.updateTreeSelectionFromURL($location, $(entaxyTreeElementId));
|
||||
ctrl.isTreeOrTabSelectionUpdateNeeded = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
entaxyProfileDiagramController.$inject = ['$scope', 'workspace', 'jolokia', '$location', '$q',
|
||||
'entaxyService', 'entaxyProfileDiagramService', 'entaxyAttributesCacheService',
|
||||
'entaxyPrivateObjectsCacheService', '$uibModal', '$route', '$cookies'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,155 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyProfileDiagramPalette', {
|
||||
template:
|
||||
`
|
||||
<div class="profile-diagram-palette">
|
||||
<div class="profile-diagram-palette-title">
|
||||
<span>
|
||||
Connectors Palette
|
||||
</span>
|
||||
<input type="search" class="form-control" placeholder="Search..." ng-model="$ctrl.filter"
|
||||
ng-keypress="$ctrl.onValueKeyPress($event)">
|
||||
</div>
|
||||
<uib-accordion>
|
||||
<div class="profile-diagram-palette-group-container">
|
||||
<entaxy-profile-diagram-palette-group heading="---IN---" is-open="$ctrl.isInGroupOpened"
|
||||
factories="$ctrl.viewedInFactories"></entaxy-profile-diagram-palette-group>
|
||||
<entaxy-profile-diagram-palette-group heading="---OUT---" is-open="$ctrl.isOutGroupOpened"
|
||||
factories="$ctrl.viewedOutFactories"></entaxy-profile-diagram-palette-group>
|
||||
</div>
|
||||
</uib-accordion>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyProfileDiagramPaletteController
|
||||
})
|
||||
.component('entaxyProfileDiagramPaletteGroup', {
|
||||
bindings: {
|
||||
heading: '@',
|
||||
isOpen: '=',
|
||||
factories: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div uib-accordion-group class="panel-default" heading="{{$ctrl.heading}}" is-open="$ctrl.isOpen">
|
||||
<div class="profile-diagram-palette-items-container">
|
||||
<div draggable class="profile-diagram-palette-item" id="{{factory.name}}"
|
||||
ng-repeat="factory in $ctrl.factories"
|
||||
data-toggle="tooltip" title="{{factory.description}}">
|
||||
<span>{{ factory.displayName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyProfileDiagramPaletteController($scope, jolokia, entaxyService, $cookies) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
populateConnectorFactories();
|
||||
|
||||
ctrl.isInGroupOpened = $cookies.getObject('diagram-palette-in-group-opened');
|
||||
ctrl.isOutGroupOpened = $cookies.getObject('diagram-palette-out-group-opened');
|
||||
}
|
||||
|
||||
function populateConnectorFactories() {
|
||||
let factories = [];
|
||||
|
||||
let factoryFolder = entaxyService.getFolderByTitle(Entaxy.RUNTIME_TYPE.CONNECTOR);
|
||||
|
||||
if (factoryFolder && factoryFolder.children) {
|
||||
factoryFolder.children.forEach((child) => {
|
||||
let attributes = jolokia.getAttribute(child.objectName);
|
||||
|
||||
if (!attributes.Abstract) {
|
||||
factories.push({
|
||||
name: attributes.Id,
|
||||
displayName: attributes.ShortName ? attributes.ShortName : attributes.Id,
|
||||
mbeanName: child.objectName,
|
||||
description: attributes.Description ?
|
||||
attributes.Description : 'There is no description for this factory.',
|
||||
direction: attributes.TypeInfo.direction,
|
||||
label: attributes.Label
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.inFactories = factories.filter(factory => factory.direction === 'in')
|
||||
.sort(Entaxy.compareBy('displayName'));
|
||||
ctrl.outFactories = factories.filter(factory => factory.direction === 'out')
|
||||
.sort(Entaxy.compareBy('displayName'));
|
||||
ctrl.viewedInFactories = ctrl.inFactories;
|
||||
ctrl.viewedOutFactories = ctrl.outFactories;
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.isInGroupOpened', function (newValue) {
|
||||
$cookies.putObject('diagram-palette-in-group-opened', newValue);
|
||||
});
|
||||
|
||||
$scope.$watch('$ctrl.isOutGroupOpened', function (newValue) {
|
||||
$cookies.putObject('diagram-palette-out-group-opened', newValue);
|
||||
});
|
||||
|
||||
ctrl.onValueKeyPress = function (keyEvent) {
|
||||
if (keyEvent.key === 'Enter') {
|
||||
keyEvent.stopPropagation();
|
||||
keyEvent.preventDefault();
|
||||
|
||||
if (ctrl.filter && ctrl.filter.length > 0) {
|
||||
filter(ctrl.filter);
|
||||
} else {
|
||||
ctrl.viewedInFactories = ctrl.inFactories;
|
||||
ctrl.viewedOutFactories = ctrl.outFactories;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function filter(filter) {
|
||||
ctrl.viewedInFactories = ctrl.inFactories.filter(factory => matchesFilter(factory, filter));
|
||||
ctrl.viewedOutFactories = ctrl.outFactories.filter(factory => matchesFilter(factory, filter));
|
||||
}
|
||||
|
||||
function matchesFilter(factory, filter) {
|
||||
let match = false;
|
||||
if (factory.displayName.toLowerCase().match(filter.toLowerCase()) !== null &&
|
||||
(factory.label && factory.label.toLowerCase().match(filter.toLowerCase()) !== null)) {
|
||||
match = true
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
entaxyProfileDiagramPaletteController.$inject = ['$scope', 'jolokia', 'entaxyService', '$cookies'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,184 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyAliases', {
|
||||
bindings: {
|
||||
objectType: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>Aliases</h2>
|
||||
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: entaxyAliasesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyAliasesController(workspace, operationsService, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMBeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
const OBJECT_TYPE = {
|
||||
KEYSTORE: 'keystore'
|
||||
}
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'name',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Name', itemField: 'name' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'name') {
|
||||
match = item.name.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
populateTable();
|
||||
|
||||
let primaryActions = [
|
||||
{ name: 'Add Alias', actionFn: () => ctrl.showAddKeyModal() }
|
||||
];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Remove', title: 'Remove Alias', actionFn: removeAlias }
|
||||
];
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
operationsService.executeOperation(selectedMBeanName, { name: 'listAliases' }, [])
|
||||
.then(aliases => {
|
||||
let items = JSON.parse(aliases);
|
||||
|
||||
ctrl.items = items.map(item => { return { name: item }; });
|
||||
ctrl.viewedItems = ctrl.items;
|
||||
|
||||
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
|
||||
if (filters.length > 0) {
|
||||
filterChange(filters);
|
||||
} else {
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.showAddKeyModal = function () {
|
||||
$uibModal.open({
|
||||
component: 'entaxyUserManagementModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Add Alias',
|
||||
formFields: () => [
|
||||
{
|
||||
label: 'Alias',
|
||||
name: 'alias',
|
||||
type: 'text',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
label: ctrl.objectType === OBJECT_TYPE.KEYSTORE ? 'Key Content' : 'Value',
|
||||
name: ctrl.objectType === OBJECT_TYPE.KEYSTORE ? 'keyContent' : 'value',
|
||||
type: 'textarea',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
processOperation(ctrl.objectType === OBJECT_TYPE.KEYSTORE ? 'addKey' : 'writeValue', args);
|
||||
},
|
||||
reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeAlias(action, item) {
|
||||
processOperation(ctrl.objectType === OBJECT_TYPE.KEYSTORE ? 'removeKey' : 'removeValue', [item.name]);
|
||||
}
|
||||
|
||||
function processOperation (operationName, properties) {
|
||||
operationsService.executeOperation(selectedMBeanName, { name: operationName }, properties)
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
populateTable();
|
||||
})
|
||||
.catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
Entaxy.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
entaxyAliasesController.$inject = ['workspace', 'operationsService', '$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,352 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyAllConnectorsTable', {
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
Connectors
|
||||
</h2>
|
||||
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
menu-actions="$ctrl.menuActions"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
|
||||
`,
|
||||
controller: EntaxyAllConnectorsTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyAllConnectorsTableController($q, workspace, $scope, operationsService,
|
||||
jolokia, jolokiaService, entaxyService,
|
||||
entaxyLegacyConnectorService, entaxyAttributesCacheService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.workspace = workspace;
|
||||
|
||||
ctrl.itemName = "Connector";
|
||||
ctrl.statusName = "BundleState";
|
||||
|
||||
let filterValues = Entaxy.getAllBundleStates();
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'displayName',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'direction',
|
||||
title: 'Direction',
|
||||
placeholder: 'Filter by Direction...',
|
||||
filterType: 'select',
|
||||
filterValues: ['in', 'out']
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'profile',
|
||||
title: 'Profile',
|
||||
placeholder: 'Filter by Profile...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
placeholder: 'Filter by Status...',
|
||||
filterType: 'select',
|
||||
filterValues: filterValues
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Direction', itemField: 'direction' },
|
||||
{ header: 'Name', itemField: 'displayName' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Profile', itemField: 'profile' },
|
||||
{ header: 'Status', itemField: 'status' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'direction') {
|
||||
match = item.direction === filter.value;
|
||||
} else if (filter.id === 'displayName') {
|
||||
match = item.displayName.match(filter.value) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type.match(filter.value) !== null;
|
||||
} else if (filter.id === 'profile') {
|
||||
match = item.profile === filter.value;
|
||||
} else if (filter.id === 'status') {
|
||||
match = item.status === filter.value;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
entaxyService.getProfiles().then(profiles => {
|
||||
ctrl.profiles = profiles.sort(Entaxy.compareBy('name'));
|
||||
populateTable();
|
||||
|
||||
let toolbarConfigFilterProfile = ctrl.toolbarConfig.filterConfig.fields
|
||||
.find(field => field.id === 'profile');
|
||||
toolbarConfigFilterProfile.filterValues = ctrl.profiles.map(profile => profile.name);
|
||||
|
||||
let primaryActions = [
|
||||
{
|
||||
name: 'Add Connector',
|
||||
actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD),
|
||||
isDisabled: ctrl.profiles.length === 0
|
||||
}//,
|
||||
// {
|
||||
// name: 'Add Legacy Connector',
|
||||
// actionFn: () => ctrl.showAddLegacyConnectorModal(),
|
||||
// isDisabled: ctrl.profiles.length === 0
|
||||
// }
|
||||
];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
});
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: checkAndProcess },
|
||||
{ name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: checkAndProcess },
|
||||
{ name: 'Edit', title: 'Edit ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal }
|
||||
];
|
||||
|
||||
ctrl.menuActions = [
|
||||
{ name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: checkAndProcess },
|
||||
{ name: 'View Properties', title: 'View ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal }
|
||||
];
|
||||
}
|
||||
|
||||
function showPropertiesModal(action, item) {
|
||||
if (action.name === 'View Properties') {
|
||||
ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
|
||||
} else if (action.name === 'Edit') {
|
||||
entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
|
||||
if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
|
||||
} else {
|
||||
item.isLocal = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL;
|
||||
ctrl.showModal(Entaxy.MODAL_MODES.EDIT, item);
|
||||
}
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
let items = [];
|
||||
|
||||
let profilesFolder = entaxyService.getDomainFolder()
|
||||
.findDescendant(child => child.objectName && child.objectName.endsWith('category=profiles'));
|
||||
|
||||
entaxyService.getAllChildMBeansByRuntimeType(profilesFolder, Entaxy.RUNTIME_TYPE.CONNECTOR)
|
||||
.then((mbeans) => {
|
||||
|
||||
mbeans.forEach(mbean => {
|
||||
let connectorSystemName = mbean.attributes.System;
|
||||
let profile = ctrl.profiles.find(profile => profile.name === connectorSystemName);
|
||||
let displayName =
|
||||
mbean.attributes.DisplayName && mbean.attributes.DisplayName.trim().length > 0 ?
|
||||
mbean.attributes.DisplayName : mbean.attributes.Name;
|
||||
let factoryId = mbean.attributes.FactoryId;
|
||||
let factoryFolder = entaxyService.getFolderByTitle(factoryId);
|
||||
if (factoryFolder) {
|
||||
jolokiaService.getAttribute(factoryFolder.objectName, 'TypeInfo')
|
||||
.then(typeInfo => {
|
||||
items.push({
|
||||
name: mbean.attributes.Name,
|
||||
displayName: displayName,
|
||||
direction: mbean.attributes.Direction ? mbean.attributes.Direction : '-',
|
||||
type: typeInfo.type,
|
||||
status: mbean.attributes[ctrl.statusName],
|
||||
mbeanName: mbean.mbean.objectName,
|
||||
profileMBeanName: profile.mbeanName,
|
||||
profile: profile.name
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.items = items;
|
||||
ctrl.viewedItems = items;
|
||||
|
||||
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
|
||||
if (filters.length > 0) {
|
||||
filterChange(filters);
|
||||
} else {
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.showModal = function(mode, item) {
|
||||
|
||||
let runtimeType = Entaxy.RUNTIME_TYPE.CONNECTOR;
|
||||
|
||||
if (mode === Entaxy.MODAL_MODES.ADD) {
|
||||
|
||||
let resolve = {
|
||||
mode: () => mode,
|
||||
itemType: () => ctrl.itemName,
|
||||
profiles: () => ctrl.profiles
|
||||
};
|
||||
|
||||
entaxyService.openAddItemModalAndProcessResults(resolve, runtimeType);
|
||||
} else {
|
||||
entaxyService.openEditItemModalAndProcessResults(item, ctrl.itemName, runtimeType, mode);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.showAddLegacyConnectorModal = function() {
|
||||
let resolve = {
|
||||
profiles: () => ctrl.profiles
|
||||
};
|
||||
|
||||
entaxyLegacyConnectorService.openAddLegacyConnectorModal(resolve).then(connectorArgs => {
|
||||
addLegacyConnector(connectorArgs);
|
||||
});
|
||||
}
|
||||
|
||||
function addLegacyConnector(connectorArgs) {
|
||||
|
||||
let args = entaxyLegacyConnectorService.getArguments(connectorArgs);
|
||||
let mbeanName = connectorArgs.profile.mbeanName;
|
||||
|
||||
operationsService.executeOperation(mbeanName, { name: 'addConnector' }, args)
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$on(Jmx.TreeEvent.Updated, () => {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function checkAndProcess(action, item) {
|
||||
entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
|
||||
if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL) {
|
||||
Entaxy.notificationInfo('Local ' + ctrl.itemName.toLowerCase() + ' cannot be ' +
|
||||
action.name.toLowerCase() +
|
||||
(action.name.toLowerCase() === Entaxy.OPERATION_TYPE.STOP ? 'ped' : 'ed'));
|
||||
} else if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
|
||||
} else {
|
||||
switch (action.name.toLowerCase()) {
|
||||
case Entaxy.OPERATION_TYPE.START:
|
||||
startItem(action, item);
|
||||
return;
|
||||
case Entaxy.OPERATION_TYPE.STOP:
|
||||
stopItem(action, item);
|
||||
return;
|
||||
case Entaxy.OPERATION_TYPE.UNINSTALL:
|
||||
uninstallItem(action, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
|
||||
function startItem(action, item) {
|
||||
if (item.status !== 'Active') {
|
||||
entaxyAttributesCacheService.setToUpdate(item.mbeanName);
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.START,
|
||||
item.name, Entaxy.RUNTIME_TYPE.CONNECTOR, item.displayName);
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemName + ' has been already started');
|
||||
}
|
||||
}
|
||||
|
||||
function stopItem(action, item) {
|
||||
if (item.status !== 'Resolved') {
|
||||
entaxyAttributesCacheService.setToUpdate(item.mbeanName);
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.STOP,
|
||||
item.name, Entaxy.RUNTIME_TYPE.CONNECTOR, item.displayName);
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemName + ' has been already stopped');
|
||||
}
|
||||
}
|
||||
|
||||
function uninstallItem(action, item) {
|
||||
let title = 'Confirm Uninstalling';
|
||||
let message = 'Do you want to uninstall ' + ctrl.itemName.toLowerCase() + ' ' + item.displayName + '?';
|
||||
|
||||
entaxyService.openConfirmationWindow(title, message).then(() => {
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.UNINSTALL,
|
||||
item.name, Entaxy.RUNTIME_TYPE.CONNECTOR, item.displayName);
|
||||
entaxyAttributesCacheService.removeFromCache(item.mbeanName);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.dismissAlert = () => ctrl.alert = null;
|
||||
|
||||
}
|
||||
EntaxyAllConnectorsTableController.$inject = ['$q', 'workspace', '$scope', 'operationsService', 'jolokia',
|
||||
'jolokiaService', 'entaxyService', 'entaxyLegacyConnectorService', 'entaxyAttributesCacheService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,130 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyConfigProperties', {
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
Configuration Properties
|
||||
</h2>
|
||||
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyConfigPropertiesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyConfigPropertiesController(workspace, $location, $scope, $q, jolokia, jolokiaService, operationsService,
|
||||
entaxyService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'displayName',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Property', itemField: 'name' },
|
||||
{ header: 'Name', itemField: 'displayName' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Value', itemField: 'value' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
return item.displayName.match(filter.value) !== null;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
let items = [];
|
||||
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
entaxyService.readConfiguration(selectedMbeanName).then(config => {
|
||||
|
||||
let itemKeys = Object.keys(config.properties);
|
||||
let configHint = JSON.parse(Entaxy.base64ToString(config.properties.__entaxy_config_hint));
|
||||
|
||||
itemKeys.forEach(key => {
|
||||
let fieldDescription = configHint.fields[key];
|
||||
|
||||
if (!fieldDescription.isInternal) {
|
||||
items.push({
|
||||
name: key,
|
||||
displayName: fieldDescription.displayName,
|
||||
type: fieldDescription.type,
|
||||
value: config.properties[key]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.items = items;
|
||||
ctrl.viewedItems = items;
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyConfigPropertiesController.$inject = ['workspace', '$location', '$scope', '$q', 'jolokia', 'jolokiaService',
|
||||
'operationsService', 'entaxyService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyConnections', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="Status" object-name="name"></entaxy-table>
|
||||
`,
|
||||
controller: EntaxyConnectionsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyConnectionsController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.CONNECTION;
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,99 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyConnectors', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}"
|
||||
status-name="BundleState" object-name="systemName"
|
||||
is-parent-dependent="true" skip-location-update="true"
|
||||
population-parent-mbean-name="$ctrl.populationParentMbeanName"></entaxy-table>
|
||||
`,
|
||||
controller: EntaxyConnectorsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyConnectorsController(workspace, operationsService, jolokia, entaxyLegacyConnectorService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.CONNECTOR;
|
||||
ctrl.workspace = workspace;
|
||||
|
||||
let primaryActions = [ { name: 'Add Legacy Connector', actionFn: () => ctrl.showAddConnectorModal() } ];
|
||||
ctrl.config = {
|
||||
primaryActions: primaryActions,
|
||||
isTableUpdateNeeded: true
|
||||
}
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
ctrl.populationParentMbeanName = selectedMbean.objectName ?
|
||||
selectedMbean.objectName : selectedMbean.parent.objectName;
|
||||
}
|
||||
|
||||
ctrl.showAddConnectorModal = function() {
|
||||
let parentMBeanName = ctrl.populationParentMbeanName ?
|
||||
ctrl.populationParentMbeanName : workspace.getSelectedMBeanName();
|
||||
|
||||
let resolve = {
|
||||
profileName: () => jolokia.getAttribute(parentMBeanName, 'Name')
|
||||
};
|
||||
|
||||
entaxyLegacyConnectorService.openAddLegacyConnectorModal(resolve).then(connectorArgs => {
|
||||
addConnector(connectorArgs);
|
||||
});
|
||||
}
|
||||
|
||||
function addConnector(connectorArgs) {
|
||||
|
||||
let args = entaxyLegacyConnectorService.getArguments(connectorArgs);
|
||||
let mbeanName = ctrl.populationParentMbeanName ?
|
||||
ctrl.populationParentMbeanName : workspace.getSelectedMBeanName();
|
||||
|
||||
operationsService.executeOperation(mbeanName, { name: 'addConnector' }, args)
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.dismissAlert = () => ctrl.alert = null;
|
||||
|
||||
}
|
||||
EntaxyConnectorsController.$inject = ['workspace', 'operationsService', 'jolokia', 'entaxyLegacyConnectorService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyKeyStores', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyKeyStoresController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyKeyStoresController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE_SECURITY.KEY_STORE;
|
||||
}
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,61 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyOperationAffectedTable', {
|
||||
bindings: {
|
||||
items: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
items="$ctrl.items">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyOperationAffectedTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyOperationAffectedTableController() {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'objectId',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Object', itemField: 'objectId' },
|
||||
{ header: 'Operation', itemField: 'action' }
|
||||
];
|
||||
|
||||
}
|
||||
EntaxyOperationAffectedTableController.$inject = [];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyProfiles', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyProfilesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyProfilesController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.PROFILE;
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyRealms', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyRealmsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyRealmsController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE_SECURITY.JAAS_REALM;
|
||||
}
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyRepositories', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyRepositoriesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyRepositoriesController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.REPOSITORY;
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyRouteLibraries', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyRouteLibrariesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyRouteLibrariesController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.ROUTE_LIBRARY;
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyRoutes', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-routes-table></entaxy-routes-table>
|
||||
`
|
||||
})
|
||||
.name;
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,366 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyRoutesTable', {
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems"
|
||||
ng-if="$ctrl.ready">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyRoutesTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyRoutesTableController(workspace, $location, $scope, $uibModal, entaxyService,
|
||||
entaxyAttributesCacheService, entaxyPrivateObjectsCacheService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.workspace = workspace;
|
||||
|
||||
const STATUS = {
|
||||
NEW: 'New',
|
||||
TO_REMOVAL: 'To Removal'
|
||||
};
|
||||
|
||||
let filterValues = Entaxy.getAllBundleStates();
|
||||
filterValues.push(STATUS.NEW);
|
||||
filterValues.push(STATUS.TO_REMOVAL);
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'displayName',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
placeholder: 'Filter by Status...',
|
||||
filterType: 'select',
|
||||
filterValues: filterValues
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Name', itemField: 'displayName' },
|
||||
{ header: 'Status', itemField: 'status' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
}
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'displayName') {
|
||||
match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
} else if (filter.id === 'status') {
|
||||
match = item.status.match(filter.value) !== null;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.ROUTE;
|
||||
|
||||
populateTable();
|
||||
|
||||
ctrl.itemType = Entaxy.getItemTypeFromRuntimeType(ctrl.runtimeType);
|
||||
|
||||
populateActionButtons();
|
||||
}
|
||||
|
||||
function populateActionButtons() {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
let ownerMbean = selectedMbean.parent;
|
||||
entaxyService.readExtendedData(ownerMbean.objectName)
|
||||
.then(result => {
|
||||
let extendedData = JSON.parse(result);
|
||||
|
||||
if (!extendedData.applications) {
|
||||
let primaryActions = [ { name: 'Add ' + ctrl.itemType, actionFn: () => ctrl.showModal() } ];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Remove', title: 'Remove ' + ctrl.itemType, actionFn: removeItem },
|
||||
{ name: 'Restore', title: 'Restore ' + ctrl.itemType, actionFn: restoreItem }
|
||||
];
|
||||
}
|
||||
|
||||
ctrl.ready = true;
|
||||
});
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
let selectedMBean = workspace.getSelectedMBean();
|
||||
if (selectedMBean && selectedMBean.isFolder) {
|
||||
let items = [];
|
||||
let children = selectedMBean.children;
|
||||
if (children && children.length > 0) {
|
||||
let mbeans = [];
|
||||
children.forEach(child => {
|
||||
if (child.objectName) {
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(child.objectName);
|
||||
if (attributes.RuntimeType === ctrl.runtimeType) {
|
||||
mbeans.push({ mbean: child, attributes: attributes });
|
||||
}
|
||||
}
|
||||
});
|
||||
items = createItemsFromMbeans(mbeans);
|
||||
}
|
||||
|
||||
if (entaxyPrivateObjectsCacheService.hasAddedChildren(selectedMBean.objectName)) {
|
||||
items = items.concat(createItemsFromAddedObjectsInfo(selectedMBean.objectName));
|
||||
}
|
||||
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
}
|
||||
}
|
||||
|
||||
function createItemsFromMbeans(mbeans) {
|
||||
let items = [];
|
||||
mbeans.forEach((mbean) => {
|
||||
let displayName = mbean.attributes.DisplayName &&
|
||||
mbean.attributes.DisplayName.trim().length > 0 ?
|
||||
mbean.attributes.DisplayName : mbean.attributes.Name;
|
||||
let changedObjectInfo = entaxyPrivateObjectsCacheService
|
||||
.getChangedObjectInfo(mbean.attributes.ObjectFullId);
|
||||
items.push({
|
||||
id: mbean.attributes.Name,
|
||||
routeId: mbean.attributes.RouteId,
|
||||
displayName: displayName,
|
||||
status: changedObjectInfo && changedObjectInfo.toRemoval ?
|
||||
mbean.attributes.BundleState + ' [' + STATUS.TO_REMOVAL + ']' :
|
||||
mbean.attributes.BundleState,
|
||||
mbeanName: mbean.mbean.objectName,
|
||||
objectFullId: mbean.attributes.ObjectFullId,
|
||||
toRemoval: changedObjectInfo && changedObjectInfo.toRemoval
|
||||
});
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
function createItemsFromAddedObjectsInfo(selectedMBeanMame) {
|
||||
let items = [];
|
||||
entaxyPrivateObjectsCacheService.getAddedObjectsInfo(selectedMBeanMame).forEach(addedObject => {
|
||||
items.push({
|
||||
id: addedObject.ui.id,
|
||||
routeId: addedObject.properties.routeId,
|
||||
displayName: addedObject.properties.displayName ?
|
||||
addedObject.properties.displayName : addedObject.ui.id,
|
||||
status: addedObject.toRemoval ? STATUS.NEW + ' [' + STATUS.TO_REMOVAL + ']' : STATUS.NEW,
|
||||
added: true,
|
||||
toRemoval: addedObject.toRemoval
|
||||
});
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
ctrl.showModal = function() {
|
||||
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(selectedMbeanName);
|
||||
let ownerRuntimeType = attributes.ObjectType;
|
||||
let ownerFactoryId = attributes.FactoryId;
|
||||
|
||||
let factoryMbean = entaxyService.getFolderByTitle(ownerRuntimeType).get(ownerFactoryId);
|
||||
|
||||
entaxyService.getFields(factoryMbean.objectName).then(result => {
|
||||
let fields = JSON.parse(result);
|
||||
let routesField = fields.find(field => field.name === 'routes');
|
||||
let factoryFilter = routesField && routesField.itemFactory ?
|
||||
routesField.itemFactory.filter : undefined;
|
||||
|
||||
entaxyService.getFactoriesByFilterSearch(factoryFilter, true).then(factories => {
|
||||
|
||||
let typeInfo = routesField['@TYPEINFO'];
|
||||
let validation = typeInfo ? typeInfo.validation : undefined;
|
||||
|
||||
let checkUniqueness = validation && validation.rules && validation.rules.checkUniqueness ?
|
||||
validation.rules.checkUniqueness : undefined;
|
||||
let checkUniquenessFields = {};
|
||||
if (checkUniqueness) {
|
||||
checkUniqueness.fields.forEach(field => {
|
||||
checkUniquenessFields[field] = [];
|
||||
if (ctrl.items) {
|
||||
ctrl.items.forEach(item => {
|
||||
if (item[field]) {
|
||||
checkUniquenessFields[field].push(item[field]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let itemTypes = typeInfo && typeInfo.privateObjectTypes ?
|
||||
typeInfo.privateObjectTypes.map(type => type.displayName).join(' or ') : 'Route';
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyModal',
|
||||
resolve: {
|
||||
mode: () => Entaxy.MODAL_MODES.ADD,
|
||||
itemType: () => itemTypes,
|
||||
factories: () => factories,
|
||||
returnFormFields: () => true,
|
||||
checkUniquenessParentFields: () => checkUniquenessFields
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-override'
|
||||
})
|
||||
.result.then(formFields => {
|
||||
// object full id of route-container actually has object full id of its owner
|
||||
let ownerFullId = attributes.ObjectFullId;
|
||||
|
||||
addItem(formFields, routesField, factories, ownerFullId, typeInfo.useAsIdentifier);
|
||||
},
|
||||
reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addItem(formFields, routesField, factories, ownerFullId, identifierFieldName) {
|
||||
let args = entaxyService.getArguments(formFields, factories);
|
||||
|
||||
let objectId = args.fields.find(field => field.name === 'objectId').value;
|
||||
let argFields = args.fields.filter(field => field.name !== 'objectId');
|
||||
let properties = argFields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});
|
||||
if (!identifierFieldName) {
|
||||
identifierFieldName = 'routeId';
|
||||
}
|
||||
let routeType = args.factoryId.attributes['typeinfo.routeType'];
|
||||
|
||||
let itemInfo = {
|
||||
objectId: objectId,
|
||||
factoryId: args.factoryId.name,
|
||||
scope: routesField.itemScope,
|
||||
type: routesField.itemType,
|
||||
properties: properties,
|
||||
ui: {
|
||||
id: properties[identifierFieldName],
|
||||
identifierFieldName: identifierFieldName,
|
||||
formFields: formFields,
|
||||
owner: ownerFullId,
|
||||
routeType: routeType
|
||||
}
|
||||
};
|
||||
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
entaxyPrivateObjectsCacheService.addNew(selectedMbean, itemInfo);
|
||||
|
||||
workspace.loadTree();
|
||||
changeLocation(itemInfo.ui.id);
|
||||
}
|
||||
|
||||
function changeLocation(itemName) {
|
||||
let currentLocation = $location.search();
|
||||
$location.search('nid', currentLocation.nid + '-' + itemName);
|
||||
}
|
||||
|
||||
$scope.$on(Jmx.TreeEvent.Updated, () => {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function removeItem(action, item) {
|
||||
|
||||
if (!item.toRemoval) {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
if (item.added) {
|
||||
entaxyPrivateObjectsCacheService.setAddedObjectToRemoval(selectedMbean.objectName, item.id);
|
||||
} else {
|
||||
entaxyService.readConfiguration(item.mbeanName).then(config => {
|
||||
entaxyPrivateObjectsCacheService.setObjectToRemoval(item.objectFullId, item.mbeanName, config);
|
||||
});
|
||||
}
|
||||
|
||||
workspace.loadTree();
|
||||
|
||||
Entaxy.notificationSuccess('Operation Succeeded');
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemType + ' has been already set to removal');
|
||||
}
|
||||
}
|
||||
|
||||
function restoreItem (action, item) {
|
||||
if (item.toRemoval) {
|
||||
if (item.added) {
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
entaxyPrivateObjectsCacheService.restoreAddedObject(selectedMbeanName, item.id);
|
||||
} else {
|
||||
entaxyPrivateObjectsCacheService.restoreObject(item.objectFullId);
|
||||
}
|
||||
|
||||
workspace.loadTree();
|
||||
|
||||
Entaxy.notificationSuccess('Operation Succeeded');
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemType + ' has been already restored');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.dismissAlert = () => ctrl.alert = null;
|
||||
|
||||
}
|
||||
EntaxyRoutesTableController.$inject = ['workspace', '$location', '$scope', '$uibModal', 'entaxyService',
|
||||
'entaxyAttributesCacheService', 'entaxyPrivateObjectsCacheService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyServices', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyServicesController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyServicesController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE.SERVICE;
|
||||
}
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,306 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module
|
||||
.component('entaxyTable', {
|
||||
bindings: {
|
||||
runtimeType: '@',
|
||||
statusName: '@',
|
||||
objectName: '@',
|
||||
isParentDependent: '<',
|
||||
extraPrimaryActionsConfig: '<',
|
||||
populationParentMbeanName: '<',
|
||||
skipLocationUpdate: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
menu-actions="$ctrl.menuActions"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyTableController(workspace, $location, $scope, $q, jolokia, jolokiaService, operationsService,
|
||||
entaxyService, entaxyAttributesCacheService) {
|
||||
'ngInject';
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.workspace = workspace;
|
||||
|
||||
let filterValues = Entaxy.getAllBundleStates();
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'displayName',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
placeholder: 'Filter by Status...',
|
||||
filterType: 'select',
|
||||
filterValues: filterValues
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Name', itemField: 'displayName' },
|
||||
{ header: 'Status', itemField: 'status' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
}
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'displayName') {
|
||||
match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
} else if (filter.id === 'status') {
|
||||
match = item.status === filter.value;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
populateTable();
|
||||
|
||||
ctrl.itemType = Entaxy.getItemTypeFromRuntimeType(ctrl.runtimeType);
|
||||
|
||||
let primaryActions = [ { name: 'Add ' + ctrl.itemType, actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD) } ];
|
||||
|
||||
if (ctrl.extraPrimaryActionsConfig) {
|
||||
let extraPrimaryActions = ctrl.extraPrimaryActionsConfig.primaryActions;
|
||||
primaryActions = primaryActions.concat(extraPrimaryActions);
|
||||
|
||||
if (ctrl.extraPrimaryActionsConfig.isTableUpdateNeeded) {
|
||||
ctrl.extraPrimaryActionsConfig.updateTableFn = populateTable;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Start', title: 'Start ' + ctrl.itemType, actionFn: checkAndProcess },
|
||||
{ name: 'Stop', title: 'Stop ' + ctrl.itemType, actionFn: checkAndProcess },
|
||||
{ name: 'Edit', title: 'Edit ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal }
|
||||
];
|
||||
|
||||
ctrl.menuActions = [
|
||||
{ name: 'Uninstall', title: 'Uninstall ' + ctrl.itemType, actionFn: checkAndProcess },
|
||||
{ name: 'View Properties', title: 'View ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal }
|
||||
];
|
||||
}
|
||||
|
||||
function showPropertiesModal(action, item) {
|
||||
if (action.name === 'View Properties') {
|
||||
ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
|
||||
} else if (action.name === 'Edit') {
|
||||
entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
|
||||
if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
|
||||
} else {
|
||||
item.isLocal = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL;
|
||||
ctrl.showModal(Entaxy.MODAL_MODES.EDIT, item);
|
||||
}
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
let items = [];
|
||||
|
||||
let selectedMBean = ctrl.populationParentMbeanName ?
|
||||
entaxyService.getDomainFolder()
|
||||
.findDescendant(child => child.objectName === ctrl.populationParentMbeanName) :
|
||||
workspace.getSelectedMBean();
|
||||
if (selectedMBean && selectedMBean.isFolder) {
|
||||
entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, ctrl.runtimeType).then((mbeans) => {
|
||||
mbeans.forEach((mbean) => {
|
||||
let displayName = mbean.attributes.DisplayName &&
|
||||
mbean.attributes.DisplayName.trim().length > 0 ?
|
||||
mbean.attributes.DisplayName : mbean.attributes.Name;
|
||||
items.push({
|
||||
name: mbean.attributes.Name,
|
||||
displayName: displayName,
|
||||
status: mbean.attributes[ctrl.statusName],
|
||||
mbeanName: mbean.mbean.objectName
|
||||
});
|
||||
});
|
||||
|
||||
ctrl.items = items;
|
||||
ctrl.viewedItems = items;
|
||||
|
||||
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
|
||||
if (filters.length > 0) {
|
||||
filterChange(filters);
|
||||
} else {
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.showModal = function(mode, item) {
|
||||
|
||||
if (mode === Entaxy.MODAL_MODES.ADD) {
|
||||
|
||||
let parentMBeanName = ctrl.populationParentMbeanName ?
|
||||
ctrl.populationParentMbeanName : workspace.getSelectedMBeanName();
|
||||
|
||||
let parentName = ctrl.isParentDependent === true ?
|
||||
jolokia.getAttribute(parentMBeanName, 'Name') : undefined;
|
||||
|
||||
let resolve = {
|
||||
mode: () => mode,
|
||||
itemType: () => ctrl.itemType,
|
||||
parentName: () => parentName
|
||||
};
|
||||
|
||||
entaxyService.openAddItemModalAndProcessResults(resolve, ctrl.runtimeType, updateLocation);
|
||||
} else {
|
||||
entaxyService.openEditItemModalAndProcessResults(item, ctrl.itemType, ctrl.runtimeType, mode);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLocation(properties, objectId) {
|
||||
if (!ctrl.skipLocationUpdate) {
|
||||
let itemName =
|
||||
ctrl.runtimeType === Entaxy.RUNTIME_TYPE.REPOSITORY ||
|
||||
ctrl.runtimeType === Entaxy.RUNTIME_TYPE.ROUTE_LIBRARY ?
|
||||
objectId + '_' + ctrl.runtimeType :
|
||||
properties[ctrl.objectName] ? properties[ctrl.objectName] : objectId;
|
||||
changeLocation(itemName);
|
||||
}
|
||||
}
|
||||
|
||||
function changeLocation(itemName) {
|
||||
let currentLocation = $location.search();
|
||||
$location.search('nid', currentLocation.nid + '-' + itemName);
|
||||
}
|
||||
|
||||
$scope.$on(Jmx.TreeEvent.Updated, () => {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function checkAndProcess(action, item) {
|
||||
entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
|
||||
if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL) {
|
||||
Entaxy.notificationInfo('Local ' + ctrl.itemType.toLowerCase() + ' cannot be ' +
|
||||
action.name.toLowerCase() +
|
||||
(action.name.toLowerCase() === Entaxy.OPERATION_TYPE.STOP ? 'ped' : 'ed'));
|
||||
} else if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
|
||||
Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
|
||||
} else {
|
||||
switch (action.name.toLowerCase()) {
|
||||
case Entaxy.OPERATION_TYPE.START:
|
||||
startItem(action, item);
|
||||
return;
|
||||
case Entaxy.OPERATION_TYPE.STOP:
|
||||
stopItem(action, item);
|
||||
return;
|
||||
case Entaxy.OPERATION_TYPE.UNINSTALL:
|
||||
uninstallItem(action, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}).catch(e => Entaxy.notificationError(e));
|
||||
}
|
||||
|
||||
function startItem(action, item) {
|
||||
if (item.status !== 'Active') {
|
||||
entaxyAttributesCacheService.setToUpdate(item.mbeanName);
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.START,
|
||||
item.name, ctrl.runtimeType, item.displayName);
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemType + ' has been already started');
|
||||
}
|
||||
}
|
||||
|
||||
function stopItem(action, item) {
|
||||
if (item.status !== 'Resolved') {
|
||||
entaxyAttributesCacheService.setToUpdate(item.mbeanName);
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.STOP,
|
||||
item.name, ctrl.runtimeType, item.displayName);
|
||||
} else {
|
||||
Entaxy.notificationInfo(ctrl.itemType + ' has been already stopped');
|
||||
}
|
||||
}
|
||||
|
||||
function uninstallItem(action, item) {
|
||||
let title = 'Confirm Uninstalling';
|
||||
let message = 'Do you want to uninstall ' + ctrl.itemType.toLowerCase() + ' ' + item.displayName + '?';
|
||||
|
||||
entaxyService.openConfirmationWindow(title, message).then(() => {
|
||||
let selectedFolder = entaxyService.getDomainFolder()
|
||||
.findDescendant(child => child.objectName === item.mbeanName);
|
||||
let children = Entaxy.getChildrenRecursive(selectedFolder);
|
||||
entaxyAttributesCacheService.removeFromCache(item.mbeanName);
|
||||
if (children) {
|
||||
children.forEach(child => entaxyAttributesCacheService.removeFromCache(child.objectName));
|
||||
}
|
||||
entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.UNINSTALL,
|
||||
item.name, ctrl.runtimeType, item.displayName);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.dismissAlert = () => ctrl.alert = null;
|
||||
|
||||
}
|
||||
EntaxyTableController.$inject = ['workspace', '$location', '$scope', '$q', 'jolokia', 'jolokiaService',
|
||||
'operationsService', 'entaxyService', 'entaxyAttributesCacheService'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyVaults', {
|
||||
bindings: {
|
||||
pageTitle: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<h2>
|
||||
{{$ctrl.pageTitle}}
|
||||
</h2>
|
||||
|
||||
<entaxy-table runtime-type="{{$ctrl.runtimeType}}" status-name="BundleState" object-name="systemName">
|
||||
</entaxy-table>
|
||||
`,
|
||||
controller: EntaxyVaultsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyVaultsController() {
|
||||
let ctrl = this;
|
||||
ctrl.runtimeType = Entaxy.RUNTIME_TYPE_SECURITY.VAULT;
|
||||
}
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,110 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyAssociatedProfileSelect', {
|
||||
bindings: {
|
||||
username: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<entaxy-select-from-enum id="{{$ctrl.formField.name}}" values="$ctrl.formField.values"
|
||||
model="$ctrl.formField.value" readonly="$ctrl.formField.readOnly"
|
||||
is-empty-included="true" empty-option-name="'--No Profile--'"></entaxy-select-from-enum>
|
||||
`,
|
||||
controller: EntaxyAssociatedProfileSelectController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyAssociatedProfileSelectController(workspace, operationsService, entaxyService, $scope) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
entaxyService.getProfiles().then(profiles => {
|
||||
ctrl.formField = {
|
||||
readOnly: true,
|
||||
values: profiles.sort(Entaxy.compareBy('name')).map(profile => profile.name)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.username', function (newValue, oldValue) {
|
||||
if (newValue) {
|
||||
getAssociatedProfile();
|
||||
}
|
||||
})
|
||||
|
||||
function getAssociatedProfile() {
|
||||
operationsService
|
||||
.executeOperation(selectedMbeanName, { name: 'getAssociatedProfile' }, [ ctrl.username ])
|
||||
.then(profileName => {
|
||||
if (profileName === 'Empty string') {
|
||||
ctrl.formField.value = undefined;
|
||||
ctrl.associatedProfile = undefined;
|
||||
ctrl.formField.readOnly = false;
|
||||
} else {
|
||||
entaxyService.getProfiles().then(profiles => {
|
||||
let profile = profiles.find(profile => profile.name === profileName);
|
||||
if (profile) {
|
||||
ctrl.formField.value = profileName;
|
||||
ctrl.associatedProfile = profileName;
|
||||
} else {
|
||||
Entaxy.notificationError('Associated profile ' + profileName + ' not found');
|
||||
}
|
||||
ctrl.formField.readOnly = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.formField.value', function (newValue) {
|
||||
if (newValue !== ctrl.associatedProfile) {
|
||||
ctrl.associatedProfile = newValue;
|
||||
associateProfile();
|
||||
}
|
||||
})
|
||||
|
||||
function associateProfile() {
|
||||
let parameters = [ ctrl.username, ctrl.associatedProfile ];
|
||||
operationsService
|
||||
.executeOperation(selectedMbeanName, { name: 'associateProfile' }, parameters)
|
||||
.then(() => {
|
||||
Entaxy.notificationSuccess('Profile ' + ctrl.associatedProfile +
|
||||
' was successfully associated with user ' + ctrl.username);
|
||||
})
|
||||
.catch(error => {
|
||||
Entaxy.notificationError('An error occurred while associating profile ' + ctrl.associatedProfile +
|
||||
' to user ' + ctrl.username);
|
||||
Entaxy.log.error(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
EntaxyAssociatedProfileSelectController.$inject = ['workspace', 'operationsService', 'entaxyService', '$scope'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,210 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyGroupsAndRolesList', {
|
||||
bindings: {
|
||||
username: '<',
|
||||
reloadFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<entaxy-expandable-list items="$ctrl.items" action-buttons="$ctrl.actionButtons" use-toolbar="true"
|
||||
toolbar-action-buttons="$ctrl.toolbarActionButtons"
|
||||
enable-toolbar-action-buttons="$ctrl.username ? true : false"
|
||||
empty-state-config="$ctrl.emptyStateConfig">
|
||||
</entaxy-expandable-list>
|
||||
`,
|
||||
controller: EntaxyGroupsAndRolesListController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyGroupsAndRolesListController(workspace, operationsService, entaxyService, $q, $scope, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
let ITEM_TYPES = {
|
||||
ROLE: 'Role',
|
||||
GROUP: 'Group'
|
||||
}
|
||||
|
||||
ctrl.toolbarActionButtons = [
|
||||
{ name: 'Add Group', actionFn: () => showAddGroupModal(), isDisabled: ctrl.username ? false : true },
|
||||
{ name: 'Add Role', actionFn: () => showAddRoleModal(), isDisabled: ctrl.username ? false : true }
|
||||
];
|
||||
|
||||
ctrl.emptyStateConfig = {
|
||||
title: 'There is no selected user'
|
||||
};
|
||||
|
||||
ctrl.actionButtons = [{
|
||||
name: 'Delete',
|
||||
actionFn: deleteRoleOrGroup
|
||||
}];
|
||||
|
||||
$scope.$watch('$ctrl.username', function (newValue, oldValue) {
|
||||
if (newValue) {
|
||||
populateItems();
|
||||
} else {
|
||||
ctrl.items = [];
|
||||
}
|
||||
})
|
||||
|
||||
function populateItems() {
|
||||
let promises = [];
|
||||
promises.push(listRolesOrGroups(ctrl.username, 'listRolesForUser'));
|
||||
promises.push(listRolesOrGroups(ctrl.username, 'listGroupsForUser'));
|
||||
promises.push(operationsService.executeOperation(selectedMbeanName, { name: 'listGroups'}, []));
|
||||
|
||||
$q.all(promises).then(result => {
|
||||
let roles = JSON.parse(result[0]);
|
||||
ctrl.roles = JSON.parse(result[0]).map(role => role.name);
|
||||
|
||||
let items = [];
|
||||
|
||||
let userGroups = JSON.parse(result[1]);
|
||||
let allGroups = JSON.parse(result[2]);
|
||||
userGroups.forEach(group => {
|
||||
let groupWithRoles = allGroups.find(groupWithRoles => group.name === groupWithRoles.name);
|
||||
groupWithRoles.roles = groupWithRoles.roles.split(',').sort(Entaxy.compare());
|
||||
groupWithRoles.isGroup = true;
|
||||
|
||||
roles = roles.filter(role => !groupWithRoles.roles.includes(role.name));
|
||||
|
||||
items.push(groupWithRoles);
|
||||
});
|
||||
|
||||
items.push(...roles);
|
||||
|
||||
items.map(item => {
|
||||
item.displayName = item.name;
|
||||
if (item.roles) {
|
||||
item.sublist = item.roles.map(role => {
|
||||
return {
|
||||
displayName: role,
|
||||
typeIcon: 'pf pficon-user',
|
||||
disableRowExpansion: true
|
||||
};
|
||||
});
|
||||
} else {
|
||||
item.disableRowExpansion = true;
|
||||
}
|
||||
|
||||
item.typeIcon = item.isGroup ? 'pf pficon-users' : 'pf pficon-user';
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
ctrl.items = items.sort(Entaxy.compareBy('displayName'));
|
||||
});
|
||||
}
|
||||
|
||||
function listRolesOrGroups(username, operationName) {
|
||||
return operationsService.executeOperation(selectedMbeanName, { name: operationName }, [ username ]);
|
||||
}
|
||||
|
||||
function showAddRoleModal() {
|
||||
openUserManagementModalAndProcess(ITEM_TYPES.ROLE);
|
||||
}
|
||||
|
||||
function showAddGroupModal() {
|
||||
operationsService.executeOperation(selectedMbeanName, {name: 'listGroups'}, [])
|
||||
.then(list => {
|
||||
let items = JSON.parse(list);
|
||||
let values = items
|
||||
.filter(item => !includesGroup(item.name))
|
||||
.map(item => item.name)
|
||||
.sort(Entaxy.compare());
|
||||
openUserManagementModalAndProcess(ITEM_TYPES.GROUP, values);
|
||||
});
|
||||
}
|
||||
|
||||
function openUserManagementModalAndProcess(itemType, values) {
|
||||
if (itemType === ITEM_TYPES.GROUP && values.length === 0) {
|
||||
Entaxy.notificationInfo('There are no groups that can be added');
|
||||
return;
|
||||
}
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxyUserManagementModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Add ' + itemType + ' to ' + ctrl.username,
|
||||
formFields: () => getFormFields(itemType, values)
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
entaxyService.processUserManagementOperation('add' + itemType, args, populateItems);
|
||||
}, reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getFormFields(itemType, values) {
|
||||
let formFields = [
|
||||
{
|
||||
label: 'Username',
|
||||
name: 'username',
|
||||
type: 'text',
|
||||
required: true,
|
||||
value: ctrl.username,
|
||||
readOnly: true
|
||||
},
|
||||
{
|
||||
label: itemType + ' Name',
|
||||
name: Entaxy.uncapitalize(itemType),
|
||||
type: 'text',
|
||||
required: true,
|
||||
enum: itemType === ITEM_TYPES.GROUP ? true : false,
|
||||
values: itemType === ITEM_TYPES.GROUP ? values : undefined,
|
||||
validation: itemType === ITEM_TYPES.ROLE ? {
|
||||
checkUniqueness: true,
|
||||
values: ctrl.roles
|
||||
} : undefined
|
||||
}
|
||||
];
|
||||
|
||||
return formFields;
|
||||
}
|
||||
|
||||
function includesGroup(itemName) {
|
||||
let item = ctrl.items.find(item => item.name === itemName);
|
||||
return item && item.isGroup;
|
||||
}
|
||||
|
||||
function deleteRoleOrGroup(action, item) {
|
||||
let operationName = item.isGroup ? 'deleteGroup' : 'deleteRole';
|
||||
let postProcessFn = item.isGroup ? ctrl.reloadFn : populateItems;
|
||||
entaxyService.processUserManagementOperation(operationName, [ ctrl.username, item.name ], postProcessFn);
|
||||
}
|
||||
}
|
||||
EntaxyGroupsAndRolesListController.$inject = ['workspace', 'operationsService', 'entaxyService', '$q', '$scope',
|
||||
'$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,226 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyGroupsTable', {
|
||||
bindings: {
|
||||
reloadFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyGroupsTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyGroupsTableController(workspace, operationsService, entaxyService, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
let delimeter = ', ';
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'name',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Group',
|
||||
placeholder: 'Filter by Group...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'roles',
|
||||
title: 'Roles',
|
||||
placeholder: 'Filter by Roles...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Group', itemField: 'name' },
|
||||
{ header: 'Roles', itemField: 'roles' }
|
||||
];
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'name') {
|
||||
match = item.name.match(filter.value) !== null;
|
||||
} else if (filter.id === 'roles') {
|
||||
match = item.roles.match(filter.value) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
populateTable();
|
||||
|
||||
let primaryActions = [ { name: 'Create Group', actionFn: () => showCreateGroupModal() } ];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Add Role', title: 'Add Role', actionFn: addRole },
|
||||
{ name: 'Delete Role', title: 'Delete Role', actionFn: deleteRole }
|
||||
];
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
operationsService.executeOperation(selectedMbeanName, { name: 'listGroups' }, [])
|
||||
.then(list => {
|
||||
ctrl.items = JSON.parse(list).map(item => {
|
||||
item.roles = item.roles.replaceAll(',', delimeter);
|
||||
return item;
|
||||
});
|
||||
ctrl.viewedItems = ctrl.items;
|
||||
|
||||
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
|
||||
if (filters.length > 0) {
|
||||
filterChange(filters);
|
||||
} else {
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.items.length;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showCreateGroupModal() {
|
||||
let resolve = {
|
||||
modalTitle: () => 'Create Group',
|
||||
formFields: () => [
|
||||
{
|
||||
label: 'Group Name',
|
||||
name: 'group',
|
||||
type: 'text',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
};
|
||||
openModalAndProcessResults(resolve, 'createGroup');
|
||||
}
|
||||
|
||||
function addRole(action, item) {
|
||||
let resolve = {
|
||||
modalTitle: () => 'Add Role to Group ' + item.name,
|
||||
formFields: () => [
|
||||
{
|
||||
label: 'Group Name',
|
||||
name: 'group',
|
||||
type: 'text',
|
||||
required: true,
|
||||
value: item.name,
|
||||
readOnly: true
|
||||
},
|
||||
{
|
||||
label: 'Role Name',
|
||||
name: 'role',
|
||||
type: 'text',
|
||||
required: true,
|
||||
validation: {
|
||||
checkUniqueness: true,
|
||||
values: item.roles.split(delimeter)
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
openModalAndProcessResults(resolve, 'addGroupRole');
|
||||
}
|
||||
|
||||
function deleteRole(action, item) {
|
||||
let roles = item.roles.split(delimeter);
|
||||
roles.shift();
|
||||
if (roles.length > 0) {
|
||||
let resolve = {
|
||||
modalTitle: () => 'Delete Role from Group ' + item.name,
|
||||
formFields: () => [
|
||||
{
|
||||
name: 'group',
|
||||
type: 'text',
|
||||
required: true,
|
||||
value: item.name,
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
label: 'Role Name',
|
||||
name: 'role',
|
||||
type: 'text',
|
||||
required: true,
|
||||
enum: true,
|
||||
values: roles.sort(Entaxy.compare())
|
||||
}
|
||||
]
|
||||
};
|
||||
openModalAndProcessResults(resolve, 'deleteGroupRole');
|
||||
} else {
|
||||
Entaxy.notificationInfo('Group ' + item.name + ' doesn\'t have roles that can be deleted');
|
||||
}
|
||||
}
|
||||
|
||||
function openModalAndProcessResults(resolve, operationName) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyUserManagementModal',
|
||||
resolve: resolve,
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
entaxyService.processUserManagementOperation(operationName, args, ctrl.reloadFn);
|
||||
}, reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyGroupsTableController.$inject = ['workspace', 'operationsService', 'entaxyService', '$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyUserManagement', {
|
||||
template:
|
||||
`
|
||||
<entaxy-users change-selection="$ctrl.changeSelection" selected-username="$ctrl.selectedUsername"
|
||||
reload-fn="$ctrl.reload"></entaxy-users>
|
||||
|
||||
<h2>Groups</h2>
|
||||
<entaxy-groups-table reload-fn="$ctrl.reload"></entaxy-groups-table>
|
||||
`,
|
||||
controller: EntaxyUserManagementController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyUserManagementController($cookies, $route) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
const SELECTED_USER_KEY = 'selectedUser';
|
||||
|
||||
ctrl.$onInit = function () {
|
||||
let selectedUser = $cookies.getObject(SELECTED_USER_KEY);
|
||||
if (selectedUser) {
|
||||
ctrl.selectedUsername = selectedUser;
|
||||
$cookies.remove(SELECTED_USER_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.changeSelection = function (itemName) {
|
||||
ctrl.selectedUsername = itemName;
|
||||
}
|
||||
|
||||
ctrl.reload = function (username) {
|
||||
if (ctrl.selectedUsername !== username) {
|
||||
$cookies.putObject(SELECTED_USER_KEY, ctrl.selectedUsername);
|
||||
}
|
||||
$route.reload();
|
||||
}
|
||||
}
|
||||
EntaxyUserManagementController.$inject = ['$cookies', '$route'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,133 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyUserManagementModal', {
|
||||
bindings: {
|
||||
modalInstance: '<',
|
||||
resolve: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-modal-container simple-modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
|
||||
<span class="pficon pficon-close" aria-hidden="true"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{$ctrl.resolve.modalTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="entaxyObjectForm" class="form-horizontal">
|
||||
<div class="form-group" ng-repeat="formField in $ctrl.formFields"
|
||||
ng-class="{'has-error': $ctrl.errors[formField.name]}" ng-if="!formField.isHidden">
|
||||
<div class="col-sm-3 label-col">
|
||||
<label class="control-label" ng-class="{'required-pf': formField.required}" for="{{formField.name}}">
|
||||
{{formField.label}}
|
||||
</label>
|
||||
<button type="button" class="btn btn-link label-description-popover"
|
||||
popover-placement="auto top-left" popover-trigger="'outsideClick'"
|
||||
uib-popover="{{formField.description}}" ng-if="formField.description">
|
||||
<span class="pficon pficon-help"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<input type="{{formField.type}}" id="{{formField.name}}" class="form-control"
|
||||
ng-model="formField.value" ng-readonly="formField.readOnly"
|
||||
ng-if="!formField.enum && formField.type !== 'password' && formField.type !== 'textarea'">
|
||||
<entaxy-password-input id="{{formField.name}}" name="formField.name" model="formField.value"
|
||||
confirmation-model="formField.confirmationValue" readonly="formField.readOnly"
|
||||
ng-if="formField.type === 'password'" errors="$ctrl.errors"></entaxy-password-input>
|
||||
<entaxy-select-from-enum id="{{formField.name}}" values="formField.values"
|
||||
model="formField.value" readonly="formField.readOnly" is-empty-included="false"
|
||||
ng-if="formField.enum"></entaxy-select-from-enum>
|
||||
<textarea type="{{formField.type}}" id="{{formField.name}}" class="form-control"
|
||||
ng-model="formField.value" ng-readonly="formField.readOnly"
|
||||
ng-if="formField.type === 'textarea'"/>
|
||||
<span class="help-block" ng-show="$ctrl.errors[formField.name]">
|
||||
{{$ctrl.errors[formField.name]}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyUserManagementModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyUserManagementModalController($uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.formFields = ctrl.resolve.formFields;
|
||||
if (!ctrl.formFields || ctrl.formFields.length === 0) {
|
||||
ctrl.cancel('Fields can not be found');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
|
||||
ctrl.save = function() {
|
||||
ctrl.errors = validate();
|
||||
if (Object.keys(ctrl.errors).length === 0) {
|
||||
let args = ctrl.formFields.map(formField => formField.value);
|
||||
ctrl.modalInstance.close(args);
|
||||
}
|
||||
}
|
||||
|
||||
function validate() {
|
||||
let errors = {};
|
||||
|
||||
ctrl.formFields.forEach(formField => {
|
||||
if (formField.type === 'password' && ctrl.errors && ctrl.errors[formField.name]) {
|
||||
errors[formField.name] = ctrl.errors[formField.name];
|
||||
}
|
||||
|
||||
if (!errors[formField.name] && formField.required
|
||||
&& (!formField.value || formField.value.trim().length === 0)) {
|
||||
errors[formField.name] = Entaxy.ERROR_MESSAGE.EMPTY;
|
||||
}
|
||||
|
||||
if (!errors[formField.name] && formField.validation && formField.validation.checkUniqueness
|
||||
&& formField.validation.values.includes(formField.value)) {
|
||||
errors[formField.name] = Entaxy.ERROR_MESSAGE.UNIQUE;
|
||||
}
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
entaxyUserManagementModalController.$inject = ['$uibModal'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyUsers', {
|
||||
bindings: {
|
||||
changeSelection: '<',
|
||||
selectedUsername: '<',
|
||||
reloadFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-users-container">
|
||||
<div class="entaxy-users-table-container">
|
||||
<h2>Users</h2>
|
||||
<entaxy-users-table change-selection="$ctrl.changeSelection" reload-fn="$ctrl.reloadFn">
|
||||
</entaxy-users-table>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-user-details-container">
|
||||
<h2>
|
||||
User Details
|
||||
<span ng-if="$ctrl.selectedUsername">for {{$ctrl.selectedUsername}}</span>
|
||||
</h2>
|
||||
|
||||
<label>Associated Profile</label>
|
||||
<entaxy-associated-profile-select username="$ctrl.selectedUsername">
|
||||
</entaxy-associated-profile-select>
|
||||
|
||||
<label>Groups and Roles</label>
|
||||
<entaxy-groups-and-roles-list username="$ctrl.selectedUsername" reload-fn="$ctrl.reloadFn">
|
||||
</entaxy-groups-and-roles-list>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
.name;
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,178 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.component('entaxyUsersTable', {
|
||||
bindings: {
|
||||
changeSelection: '<',
|
||||
reloadFn: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyUsersTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyUsersTableController(workspace, operationsService, entaxyService, $uibModal, $templateCache) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
let selectedMbeanName = workspace.getSelectedMBeanName();
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'name',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{
|
||||
header: 'Name',
|
||||
itemField: 'name',
|
||||
htmlTemplate: 'users-table/name-template.html',
|
||||
colActionFn: (itemName) => ctrl.changeSelection(itemName)
|
||||
}
|
||||
];
|
||||
|
||||
$templateCache.put(
|
||||
'users-table/name-template.html',
|
||||
'<a href="" ng-click="$ctrl.handleColAction(key, value)">{{value}}</a>'
|
||||
);
|
||||
|
||||
ctrl.pageConfig = Entaxy.getStandardPageConfig();
|
||||
|
||||
function filterChange(filters) {
|
||||
ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
|
||||
};
|
||||
|
||||
function matchesFilter(item, filter) {
|
||||
let match = true;
|
||||
if (filter.id === 'name') {
|
||||
match = item.name.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
populateTable();
|
||||
|
||||
let primaryActions = [ { name: 'Add User', actionFn: () => showAddUserModal() } ];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Delete', title: 'Delete User', actionFn: deleteUser }
|
||||
];
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
operationsService.executeOperation(selectedMbeanName, { name: 'listUsers' }, [])
|
||||
.then(list => {
|
||||
ctrl.items = JSON.parse(list);
|
||||
ctrl.viewedItems = ctrl.items;
|
||||
|
||||
let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
|
||||
if (filters.length > 0) {
|
||||
filterChange(filters);
|
||||
} else {
|
||||
ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.items.length;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showAddUserModal() {
|
||||
$uibModal.open({
|
||||
component: 'entaxyUserManagementModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Add User',
|
||||
formFields: () => [
|
||||
{
|
||||
label: 'Username',
|
||||
name: 'username',
|
||||
type: 'text',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
label: 'Password',
|
||||
name: 'password',
|
||||
type: 'password',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
entaxyService.processUserManagementOperation('addUser', args, populateTable);
|
||||
},
|
||||
reason => {
|
||||
if (reason) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUser(action, item) {
|
||||
ctrl.deletedUsername = item.name;
|
||||
entaxyService.processUserManagementOperation('deleteUser', [ item.name ], reload);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
ctrl.reloadFn(ctrl.deletedUsername);
|
||||
}
|
||||
}
|
||||
EntaxyUsersTableController.$inject = ['workspace', 'operationsService', 'entaxyService', '$uibModal',
|
||||
'$templateCache'];
|
||||
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.factory('entaxyAttributesCacheService', ['jolokia',
|
||||
function(jolokia) {
|
||||
let attributesCache = {};
|
||||
|
||||
return {
|
||||
getAttributes: function (mbeanName) {
|
||||
return getAttributes(mbeanName);
|
||||
},
|
||||
setToUpdate: function (mbeanName) {
|
||||
return setToUpdate(mbeanName);
|
||||
},
|
||||
removeFromCache: function (mbeanName) {
|
||||
return removeFromCache(mbeanName);
|
||||
}
|
||||
};
|
||||
|
||||
function getAttributes(mbeanName) {
|
||||
let attributesCacheItem = attributesCache[mbeanName];
|
||||
if (attributesCacheItem) {
|
||||
if (attributesCacheItem.toUpdate) {
|
||||
let attributes = jolokia.getAttribute(mbeanName);
|
||||
attributesCacheItem.attributes = attributes;
|
||||
attributesCacheItem.toUpdate = false;
|
||||
}
|
||||
return attributesCacheItem.attributes;
|
||||
} else {
|
||||
let attributes = jolokia.getAttribute(mbeanName);
|
||||
attributesCache[mbeanName] = { attributes: attributes };
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
|
||||
function setToUpdate(mbeanName) {
|
||||
let attributesCacheItem = attributesCache[mbeanName];
|
||||
if (attributesCacheItem) {
|
||||
attributesCacheItem.toUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromCache(mbeanName) {
|
||||
delete attributesCache[mbeanName];
|
||||
}
|
||||
}
|
||||
])
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,233 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.factory('entaxyPrivateObjectsCacheService', ['workspace', 'entaxyAttributesCacheService',
|
||||
function(workspace, entaxyAttributesCacheService) {
|
||||
let changedObjectsInfo = {};
|
||||
let changedMbeanNames = {};
|
||||
let addedObjectsInfo = {};
|
||||
|
||||
return {
|
||||
addChanges: function (privateObjectMbean, id, owner, config) {
|
||||
return addChanges(privateObjectMbean, id, owner, config);
|
||||
},
|
||||
isChanged: function (mbeanName) {
|
||||
return isChanged(mbeanName);
|
||||
},
|
||||
isOwnerChanged: function (privateObjectMbean, owner) {
|
||||
return isOwnerChanged(privateObjectMbean, owner);
|
||||
},
|
||||
getChangedObjectInfo: function (id) {
|
||||
return getChangedObjectInfo(id);
|
||||
},
|
||||
getChangedObjectConfig: function (id) {
|
||||
return getChangedObjectConfig(id);
|
||||
},
|
||||
setObjectToRemoval: function (id, privateObjectMbeanName, config) {
|
||||
return setObjectToRemoval(id, privateObjectMbeanName, config);
|
||||
},
|
||||
isObjectSetToRemoval: function (id) {
|
||||
return isObjectSetToRemoval(id);
|
||||
},
|
||||
restoreObject: function (id) {
|
||||
return restoreObject(id);
|
||||
},
|
||||
addNew: function (parentMbean, privateObjectInfo) {
|
||||
return addNew(parentMbean, privateObjectInfo);
|
||||
},
|
||||
hasAddedChildren: function (parentMbeanName) {
|
||||
return hasAddedChildren(parentMbeanName);
|
||||
},
|
||||
getAddedObjectsInfo: function (parentMbeanName) {
|
||||
return getAddedObjectsInfo(parentMbeanName);
|
||||
},
|
||||
setAddedObjectToRemoval: function (parentMbeanName, id) {
|
||||
return setAddedObjectToRemoval(parentMbeanName, id);
|
||||
},
|
||||
isAddedObjectSetToRemoval: function (parentMbeanName, id) {
|
||||
return isAddedObjectSetToRemoval(parentMbeanName, id);
|
||||
},
|
||||
restoreAddedObject: function (parentMbeanName, id) {
|
||||
return restoreAddedObject(parentMbeanName, id);
|
||||
},
|
||||
removeFromCache: function (owner) {
|
||||
return removeFromCache(owner);
|
||||
},
|
||||
findOwnerMbean(descendantMbean, owner) {
|
||||
return findOwnerMbean(descendantMbean, owner);
|
||||
}
|
||||
};
|
||||
|
||||
function addChanges(privateObjectMbean, id, owner, config) {
|
||||
setChangedMbeanNamesAndUpdateTree(privateObjectMbean, owner);
|
||||
setChangedObjectInfo(id, owner, config);
|
||||
}
|
||||
|
||||
function setChangedMbeanNamesAndUpdateTree(privateObjectMbean, owner) {
|
||||
if (!changedMbeanNames[owner]) {
|
||||
let ownerMbean = findOwnerMbean(privateObjectMbean, owner);
|
||||
|
||||
changedMbeanNames[owner] = [ ownerMbean.objectName, privateObjectMbean.objectName ];
|
||||
|
||||
workspace.loadTree();
|
||||
} else {
|
||||
if (!changedMbeanNames[owner].includes(privateObjectMbean.objectName)) {
|
||||
changedMbeanNames[owner].push(privateObjectMbean.objectName);
|
||||
|
||||
workspace.loadTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setChangedObjectInfo(id, owner, config) {
|
||||
changedObjectsInfo[id] = {
|
||||
owner: owner,
|
||||
config: config
|
||||
}
|
||||
}
|
||||
|
||||
function isChanged(mbeanName) {
|
||||
return Object.values(changedMbeanNames).flat().includes(mbeanName);
|
||||
}
|
||||
|
||||
function isOwnerChanged(privateObjectMbean, owner) {
|
||||
let ownerMbean = findOwnerMbean(privateObjectMbean, owner);
|
||||
return isChanged(ownerMbean.objectName);
|
||||
}
|
||||
|
||||
function getChangedObjectInfo(id) {
|
||||
return changedObjectsInfo[id];
|
||||
}
|
||||
|
||||
function getChangedObjectConfig(id) {
|
||||
let object = getChangedObjectInfo(id);
|
||||
return object ? object.config : null;
|
||||
}
|
||||
|
||||
function setObjectToRemoval(id, privateObjectMbeanName, config) {
|
||||
if (changedObjectsInfo[id]) {
|
||||
changedObjectsInfo[id].toRemoval = true;
|
||||
} else {
|
||||
let selectedMbean = workspace.getSelectedMBean();
|
||||
|
||||
let privateObjectMbean = selectedMbean
|
||||
.findDescendant(child => child.objectName === privateObjectMbeanName);
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(privateObjectMbeanName);
|
||||
|
||||
addChanges(privateObjectMbean, id, attributes.Owner, config);
|
||||
|
||||
changedObjectsInfo[id].toRemoval = true;
|
||||
}
|
||||
}
|
||||
|
||||
function isObjectSetToRemoval(id) {
|
||||
let object = getChangedObjectInfo(id);
|
||||
return object ? object.toRemoval : undefined;
|
||||
}
|
||||
|
||||
function restoreObject(id) {
|
||||
if (changedObjectsInfo[id]) {
|
||||
delete changedObjectsInfo[id].toRemoval;
|
||||
}
|
||||
}
|
||||
|
||||
function addNew(parentMbean, privateObjectInfo) {
|
||||
let parentMbeanName = parentMbean.objectName;
|
||||
if (!addedObjectsInfo[parentMbeanName]) {
|
||||
addedObjectsInfo[parentMbeanName] = [ privateObjectInfo ];
|
||||
} else {
|
||||
addedObjectsInfo[parentMbeanName].push(privateObjectInfo);
|
||||
}
|
||||
|
||||
let owner = privateObjectInfo.ui.owner;
|
||||
let ownerMbean = findOwnerMbean(parentMbean, owner);
|
||||
|
||||
if (!changedMbeanNames[owner]) {
|
||||
changedMbeanNames[owner] = [ownerMbean.objectName];
|
||||
}
|
||||
}
|
||||
|
||||
function hasAddedChildren(parentMbeanName) {
|
||||
return addedObjectsInfo[parentMbeanName] ? true : false;
|
||||
}
|
||||
|
||||
function getAddedObjectsInfo(parentMbeanName) {
|
||||
return addedObjectsInfo[parentMbeanName];
|
||||
}
|
||||
|
||||
function setAddedObjectToRemoval(parentMbeanName, id) {
|
||||
if (addedObjectsInfo[parentMbeanName]) {
|
||||
let objectToRemoval = addedObjectsInfo[parentMbeanName]
|
||||
.find(privateObjInfo => privateObjInfo.ui.id === id);
|
||||
objectToRemoval.toRemoval = true;
|
||||
}
|
||||
}
|
||||
|
||||
function isAddedObjectSetToRemoval(parentMbeanName, id) {
|
||||
if (addedObjectsInfo[parentMbeanName]) {
|
||||
let objectToRemoval = addedObjectsInfo[parentMbeanName]
|
||||
.find(privateObjInfo => privateObjInfo.ui.id === id);
|
||||
return objectToRemoval.toRemoval;
|
||||
}
|
||||
}
|
||||
|
||||
function restoreAddedObject(parentMbeanName, id) {
|
||||
if (addedObjectsInfo[parentMbeanName]) {
|
||||
let objectToRestore = addedObjectsInfo[parentMbeanName]
|
||||
.find(privateObjInfo => privateObjInfo.ui.id === id);
|
||||
delete objectToRestore.toRemoval;
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromCache(owner) {
|
||||
delete changedMbeanNames[owner];
|
||||
removeAddedByOwner(owner);
|
||||
removeByOwner(owner);
|
||||
}
|
||||
|
||||
function removeAddedByOwner(owner) {
|
||||
addedObjectsInfo = Object.fromEntries(Object.entries(addedObjectsInfo)
|
||||
.filter(([key, value]) => value && value.length > 0 ? value[0].ui.owner !== owner : false));
|
||||
}
|
||||
|
||||
function removeByOwner(owner) {
|
||||
changedObjectsInfo = Object.fromEntries(Object.entries(changedObjectsInfo)
|
||||
.filter(([key, value]) => value.owner !== owner));
|
||||
}
|
||||
|
||||
function findOwnerMbean(descendantMbean, owner) {
|
||||
return descendantMbean.findAncestor(mbean => {
|
||||
if (mbean.objectName) {
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(mbean.objectName);
|
||||
return attributes.Id === owner;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
])
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,157 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.factory('entaxyProfileDiagramService', ['entaxyAttributesCacheService',
|
||||
function(entaxyAttributesCacheService) {
|
||||
let changes = {};
|
||||
let isDirty = false;
|
||||
let isProfileChanged = false;
|
||||
let isDefaultRouteChanged = false;
|
||||
|
||||
return {
|
||||
createChangesConfig: function (mbeanName, objectId, args, configurableOnly, connector) {
|
||||
return createChangesConfig(mbeanName, objectId, args, configurableOnly, connector);
|
||||
},
|
||||
setChanges: function (mbeanName, changesConfig) {
|
||||
return setChanges(mbeanName, changesConfig)
|
||||
},
|
||||
hasChanges: function (mbeanName) {
|
||||
return hasChanges(mbeanName);
|
||||
},
|
||||
getChanges: function (mbeanName) {
|
||||
return getChanges(mbeanName);
|
||||
},
|
||||
getArgs: function (mbeanName) {
|
||||
return getArgs(mbeanName);
|
||||
},
|
||||
hasType: function (mbeanName, type) {
|
||||
return hasType(mbeanName, type);
|
||||
},
|
||||
setProfileChanged: function () {
|
||||
isProfileChanged = true;
|
||||
},
|
||||
isProfileChanged: function () {
|
||||
return isProfileChanged;
|
||||
},
|
||||
setDefaultRouteChanged: function () {
|
||||
isDefaultRouteChanged = true;
|
||||
},
|
||||
isDefaultRouteChanged: function () {
|
||||
return isDefaultRouteChanged;
|
||||
},
|
||||
setConnectorChanged: function (mbeanName, isChanged) {
|
||||
return setConnectorChanged(mbeanName, isChanged);
|
||||
},
|
||||
isConnectorChanged: function (mbeanName) {
|
||||
return isConnectorChanged(mbeanName);
|
||||
},
|
||||
resetChanges: function (objectId) {
|
||||
return resetChanges(objectId);
|
||||
},
|
||||
isDirty: function () {
|
||||
return isDirty;
|
||||
},
|
||||
setDirty: function () {
|
||||
isDirty = true;
|
||||
},
|
||||
clear: function () {
|
||||
changes = {};
|
||||
isDirty = false;
|
||||
isProfileChanged = false;
|
||||
isDefaultRouteChanged = false;
|
||||
}
|
||||
};
|
||||
|
||||
function createChangesConfig(mbeanName, objectId, args, configurableOnly, connector) {
|
||||
let attributes = entaxyAttributesCacheService.getAttributes(mbeanName);
|
||||
|
||||
return {
|
||||
objectId: objectId,
|
||||
type: attributes.RuntimeType,
|
||||
args: args,
|
||||
configurableOnly: configurableOnly,
|
||||
connector: connector
|
||||
};
|
||||
}
|
||||
|
||||
function setChanges(mbeanName, changesConfig) {
|
||||
changes[mbeanName] = changesConfig;
|
||||
}
|
||||
|
||||
function hasChanges(mbeanName) {
|
||||
return changes[mbeanName] ? true : false;
|
||||
}
|
||||
|
||||
function getChanges(mbeanName) {
|
||||
return changes[mbeanName];
|
||||
}
|
||||
|
||||
function getArgs(mbeanName) {
|
||||
return hasChanges(mbeanName) ? changes[mbeanName].args : null;
|
||||
}
|
||||
|
||||
function hasType(mbeanName, type) {
|
||||
return hasChanges(mbeanName) && changes[mbeanName].type === type;
|
||||
}
|
||||
|
||||
function setConnectorChanged(mbeanName, isChanged) {
|
||||
if (hasChanges(mbeanName) && changes[mbeanName].connector) {
|
||||
changes[mbeanName].connector.isChanged = isChanged;
|
||||
}
|
||||
}
|
||||
|
||||
function isConnectorChanged(mbeanName) {
|
||||
return changes[mbeanName] && changes[mbeanName].connector && changes[mbeanName].connector.isChanged;
|
||||
}
|
||||
|
||||
function resetChanges(objectId) {
|
||||
let hasChangedConnectors = false;
|
||||
let mbeanNameToRemove;
|
||||
Object.keys(changes).forEach(mbeanName => {
|
||||
if (changes[mbeanName].objectId === objectId) {
|
||||
if (changes[mbeanName].type === Entaxy.RUNTIME_TYPE.PROFILE) {
|
||||
isProfileChanged = false;
|
||||
} else if (changes[mbeanName].type === Entaxy.RUNTIME_TYPE.DEFAULT_ROUTE) {
|
||||
isDefaultRouteChanged = false;
|
||||
} else if (changes[mbeanName].type === Entaxy.RUNTIME_TYPE.CONNECTOR) {
|
||||
setConnectorChanged(mbeanName, false);
|
||||
}
|
||||
mbeanNameToRemove = mbeanName;
|
||||
} else {
|
||||
if (changes[mbeanName].type === Entaxy.RUNTIME_TYPE.CONNECTOR &&
|
||||
changes[mbeanName].connector && changes[mbeanName].connector.isChanged) {
|
||||
hasChangedConnectors = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
isDirty = hasChangedConnectors || isProfileChanged || isDefaultRouteChanged;
|
||||
delete changes[mbeanNameToRemove];
|
||||
}
|
||||
}
|
||||
])
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,225 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.factory('entaxyResourcesService', ['workspace', 'operationsService', '$q', '$uibModal', 'restService',
|
||||
function(workspace, operationsService, $q, $uibModal, restService) {
|
||||
|
||||
const resourceMbean = getDomainFolder().findDescendant(child =>
|
||||
child.objectName && child.objectName.endsWith('category=resource'));
|
||||
|
||||
return {
|
||||
getProviderMbean: function (protocol) {
|
||||
return getProviderMbean(protocol);
|
||||
},
|
||||
getResource: function (location) {
|
||||
return getResource(location);
|
||||
},
|
||||
getResourceMetadata: function (location) {
|
||||
return getResourceMetadata(location);
|
||||
},
|
||||
getResourcesInfo: function (providerMBeanName, path) {
|
||||
return getResourcesInfo(providerMBeanName, path);
|
||||
},
|
||||
pasteResource: function (providerMBeanName, fromPath, fullToPath) {
|
||||
return pasteResource(providerMBeanName, fromPath, fullToPath);
|
||||
},
|
||||
removeResource: function (providerMBeanName, path) {
|
||||
return removeResource(providerMBeanName, path);
|
||||
},
|
||||
downloadResource: function (providerMBeanName, path) {
|
||||
return downloadResource(providerMBeanName, path);
|
||||
},
|
||||
uploadFile: function (file, protocol, path) {
|
||||
return uploadFile(file, protocol, path);
|
||||
},
|
||||
getPath: function (crumbs) {
|
||||
return getPath(crumbs);
|
||||
},
|
||||
addFolder: function (items, clientFolders, crumbs) {
|
||||
return addFolder(items, clientFolders, crumbs);
|
||||
},
|
||||
createFolder: function (name, crumbs) {
|
||||
return createFolder(name, crumbs);
|
||||
},
|
||||
getClientFoldersToAdd: function (clientFolders, items, crumbs) {
|
||||
return getClientFoldersToAdd(clientFolders, items, crumbs);
|
||||
}
|
||||
};
|
||||
|
||||
function getDomainFolder() {
|
||||
let entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";
|
||||
return workspace.tree.get(entaxyJmxDomain);
|
||||
}
|
||||
|
||||
function getProviderMbean(protocol) {
|
||||
return getDomainFolder().findDescendant(child =>
|
||||
child.objectName && child.objectName.endsWith('provider=' + protocol));
|
||||
}
|
||||
|
||||
function getResource(location) {
|
||||
return executeOperationOnResourceMbean('getResource', [location]);
|
||||
}
|
||||
|
||||
function getResourceMetadata(location) {
|
||||
return executeOperationOnResourceMbean('getResourceMetadata', [location]);
|
||||
}
|
||||
|
||||
function executeOperationOnResourceMbean(operationName, properties) {
|
||||
let resourceObjectName = resourceMbean ? resourceMbean.objectName : undefined;
|
||||
|
||||
if (resourceObjectName) {
|
||||
return operationsService.executeOperation(
|
||||
resourceObjectName,
|
||||
{ name: operationName },
|
||||
properties
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getResourcesInfo(providerMBeanName, path) {
|
||||
return $q(function (resolve) {
|
||||
operationsService.executeOperation(providerMBeanName, { name: 'getResourcesInfo' }, [ path ])
|
||||
.then((result) => {
|
||||
let items = JSON.parse(result);
|
||||
items.forEach(item => {
|
||||
if (item.metadata) {
|
||||
Object.keys(item.metadata).forEach(section => {
|
||||
item.metadata[section] = JSON.parse(item.metadata[section]);
|
||||
|
||||
if (item.metadata[section].error && !item.error) {
|
||||
let error = item.metadata[section].error;
|
||||
item.error = error.message && error.message.length > 0 ?
|
||||
error.message : error.exception;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
resolve(items);
|
||||
})
|
||||
.catch((error) => {
|
||||
Entaxy.log.error(error);
|
||||
Entaxy.notificationError('An error occurred while getting resources.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pasteResource(providerMBeanName, fromPath, fullToPath) {
|
||||
return operationsService
|
||||
.executeOperation(providerMBeanName, { name: 'pasteResource' }, [ fromPath, fullToPath ]);
|
||||
}
|
||||
|
||||
function removeResource(providerMBeanName, path) {
|
||||
return operationsService.executeOperation(providerMBeanName, { name: 'removeResource' }, [ path ]);
|
||||
}
|
||||
|
||||
function downloadResource(providerMBeanName, path) {
|
||||
return operationsService.executeOperation(providerMBeanName, { name: 'downloadResource' }, [ path ]);
|
||||
}
|
||||
|
||||
function uploadFile(file, protocol, path) {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
let fd = new FormData();
|
||||
fd.append('file', file);
|
||||
fd.append('protocol', protocol);
|
||||
fd.append('path', path);
|
||||
|
||||
return restService.post('/cxf/file-upload/upload/resource', fd);
|
||||
}
|
||||
|
||||
function getPath(crumbs) {
|
||||
let path = '';
|
||||
if (crumbs && crumbs.length > 0) {
|
||||
path = crumbs.join('/');
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
function addFolder(items, clientFolders, crumbs) {
|
||||
|
||||
$uibModal.open({
|
||||
component: 'entaxySimpleResourceNameInputModal',
|
||||
resolve: {
|
||||
title: () => 'Set folder name',
|
||||
names: () => items.filter((item) => item.isFolder).map((item) => item.name),
|
||||
type: () => 'Folder'
|
||||
},
|
||||
size: 'sm-custom',
|
||||
backdrop: 'static',
|
||||
windowTopClass: 'modal-top-margin-center-override'
|
||||
})
|
||||
.result.then(name => {
|
||||
|
||||
let newFolder = createFolder(name, crumbs);
|
||||
|
||||
items.push(newFolder);
|
||||
items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
|
||||
clientFolders.push(newFolder);
|
||||
});
|
||||
}
|
||||
|
||||
function createFolder(name, crumbs) {
|
||||
return {
|
||||
name: name,
|
||||
isFolder: true,
|
||||
crumbs: Entaxy.deepCopy(crumbs)
|
||||
};
|
||||
}
|
||||
|
||||
function getClientFoldersToAdd(clientFolders, items, crumbs) {
|
||||
let foldersToAdd = [];
|
||||
|
||||
if (clientFolders.length > 0) {
|
||||
|
||||
clientFolders = clientFolders.filter((folder) => {
|
||||
let isSaved = true;
|
||||
if (folder.crumbs.length == crumbs.length && (folder.crumbs.length == 0 ||
|
||||
(folder.crumbs.length > 0 && folder.crumbs[folder.crumbs.length - 1] ===
|
||||
crumbs[crumbs.length - 1]))) {
|
||||
|
||||
items.forEach((item) => {
|
||||
if (item.isFolder && item.name === folder.name) {
|
||||
isSaved = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (isSaved) {
|
||||
foldersToAdd.push(folder);
|
||||
}
|
||||
}
|
||||
return isSaved;
|
||||
});
|
||||
}
|
||||
|
||||
return foldersToAdd;
|
||||
}
|
||||
}
|
||||
])
|
||||
})(Entaxy || (Entaxy = {}));
|
@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
|
||||
var Entaxy;
|
||||
(function (Entaxy) {
|
||||
Entaxy._module.factory('restService', ['$q', '$http',
|
||||
function($q, $http) {
|
||||
return {
|
||||
post: function (url, data) {
|
||||
return post(url, data);
|
||||
}
|
||||
};
|
||||
|
||||
function post(url, data) {
|
||||
var deferred = $q.defer();
|
||||
$http({
|
||||
method: 'POST',
|
||||
url: url,
|
||||
data: data,
|
||||
transformRequest: angular.identity,
|
||||
headers: {'Content-Type': undefined}
|
||||
}).then(function(response) {
|
||||
deferred.resolve(response);
|
||||
}, function(response) {
|
||||
deferred.reject(response);
|
||||
}).catch(function(fallback) {
|
||||
Entaxy.log.error(fallback);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
}
|
||||
]);
|
||||
})(Entaxy || (Entaxy = {}));
|
Reference in New Issue
Block a user