release version 1.11.0
This commit is contained in:
@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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~~~~~~
|
||||
*/
|
||||
package ru.entaxy.ui.hawtio.cicd;
|
||||
|
||||
import io.hawt.web.plugin.HawtioPlugin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
/**
|
||||
* The Plugin Context Listener used to load in the plugin
|
||||
**/
|
||||
public class PluginContextListener implements ServletContextListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PluginContextListener.class);
|
||||
|
||||
HawtioPlugin plugin = null;
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||
|
||||
ServletContext context = servletContextEvent.getServletContext();
|
||||
|
||||
plugin = new HawtioPlugin();
|
||||
plugin.setContext(context.getContextPath());
|
||||
plugin.setName(context.getInitParameter("plugin-name"));
|
||||
plugin.setScripts(context.getInitParameter("plugin-scripts"));
|
||||
plugin.setDomain(null);
|
||||
|
||||
try {
|
||||
plugin.init();
|
||||
} catch (Exception e) {
|
||||
throw createServletException(e);
|
||||
}
|
||||
|
||||
LOG.info("Initialized {} plugin", plugin.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||
try {
|
||||
plugin.destroy();
|
||||
} catch (Exception e) {
|
||||
throw createServletException(e);
|
||||
}
|
||||
|
||||
LOG.info("Destroyed {} plugin", plugin.getName());
|
||||
}
|
||||
|
||||
protected RuntimeException createServletException(Exception e) {
|
||||
return new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~~~~~~licensing~~~~~~
|
||||
entaxy-cicd-plugin
|
||||
==========
|
||||
Copyright (C) 2020 - 2025 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~~~~~~
|
||||
-->
|
||||
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
|
||||
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<description>Entaxy HawtIO management plugin</description>
|
||||
<display-name>entaxy hawt.io management plugin</display-name>
|
||||
|
||||
<context-param>
|
||||
<description>Plugin's path on the server</description>
|
||||
<param-name>plugin-context</param-name>
|
||||
<param-value>${plugin-context}</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<description>Plugin's path on the server</description>
|
||||
<param-name>plugin-name</param-name>
|
||||
<param-value>${plugin-name}</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<description>Plugin's path on the server</description>
|
||||
<param-name>plugin-domain</param-name>
|
||||
<param-value>${plugin-domain}</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<description>Plugin's path on the server</description>
|
||||
<param-name>plugin-scripts</param-name>
|
||||
<param-value>${plugin-scripts}</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<description>Disable listing of directories and files</description>
|
||||
<param-name>org.eclipse.jetty.servlet.Default.dirAllowed</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>ru.entaxy.ui.hawtio.cicd.PluginContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
</web-app>
|
@ -0,0 +1,193 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdApplication', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-zero-revision-note" ng-if="$ctrl.isRevisionSelected && $ctrl.revision === '0'">
|
||||
<entaxy-form-field-extra-info type="'info'" message="$ctrl.zeroRevisionNote"></entaxy-form-field-extra-info>
|
||||
</div>
|
||||
<div ng-if="$ctrl.versions || $ctrl.isVersionSelected || $ctrl.isRevisionSelected"
|
||||
class="entaxy-cicd-header-container">
|
||||
<div class="entaxy-cicd-title-with-info-container">
|
||||
<span class="first" ng-class="{'lead': !$ctrl.isVersionSelected && !$ctrl.isRevisionSelected}">
|
||||
Application: {{$ctrl.application}}
|
||||
</span>
|
||||
<span ng-class="{'lead': $ctrl.isVersionSelected}"
|
||||
ng-if="$ctrl.isVersionSelected || $ctrl.isRevisionSelected">
|
||||
Version: {{$ctrl.version}}
|
||||
</span>
|
||||
<div ng-if="!$ctrl.isVersionSelected && !$ctrl.isRevisionSelected">
|
||||
<span>Version:</span>
|
||||
<entaxy-select-from-enum values="$ctrl.versions" model="$ctrl.version"
|
||||
is-empty-included="false"></entaxy-select-from-enum>
|
||||
</div>
|
||||
<span ng-if="$ctrl.isVersionSelected">
|
||||
Last Revision: {{$ctrl.lastRevision}}
|
||||
</span>
|
||||
<span ng-if="$ctrl.isVersionSelected">
|
||||
Installed Revision: {{$ctrl.installedRevision}}
|
||||
</span>
|
||||
<span class="lead" ng-if="$ctrl.isRevisionSelected">
|
||||
Revision: {{$ctrl.revision}}
|
||||
</span>
|
||||
<span ng-if="$ctrl.isRevisionSelected">
|
||||
Revision Status: {{$ctrl.revisionStatus}}
|
||||
</span>
|
||||
</div>
|
||||
<div ng-if="$ctrl.isRevisionSelected" class="entaxy-cicd-header-buttons-container">
|
||||
<entaxy-ci-cd-application-management-buttons storage="$ctrl.storage" application="$ctrl.application"
|
||||
version="$ctrl.version" revision="$ctrl.revision" revision-status="$ctrl.revisionStatus">
|
||||
</entaxy-ci-cd-application-management-buttons>
|
||||
</div>
|
||||
<div class="dropdown primary-action entaxy-cicd-header-buttons-container"
|
||||
uib-dropdown ng-if="$ctrl.isVersionSelected">
|
||||
<button class="dropdown-toggle" uib-dropdown-toggle type="button">
|
||||
Add Revision
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li role="menuitem" ng-click="$ctrl.addRevision()">
|
||||
<a class="secondary-action">Add Revision</a>
|
||||
</li>
|
||||
<li role="menuitem" ng-click="$ctrl.addRevisionFromExistent()">
|
||||
<a class="secondary-action">Add Revision From Existent</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-cicd-content-container">
|
||||
<h2 class="first">
|
||||
Items
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-application-items version="$ctrl.version"></entaxy-ci-cd-application-items>
|
||||
|
||||
<h2>
|
||||
Requirements
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-requirements version="$ctrl.version" type="Application"></entaxy-ci-cd-requirements>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDApplicationController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDApplicationController(workspace, $uibModal, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.zeroRevisionNote = 'Revision 0 cannot be configured';
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
ctrl.application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
|
||||
ctrl.isVersionSelected = EntaxyCICD.isVersion(workspace.selection);
|
||||
ctrl.isRevisionSelected = EntaxyCICD.isRevision(workspace.selection);
|
||||
|
||||
if (ctrl.isVersionSelected || ctrl.isRevisionSelected) {
|
||||
ctrl.version = EntaxyCICD.getVersion(workspace.selection);
|
||||
|
||||
if (ctrl.isRevisionSelected) {
|
||||
let revisionInfo = EntaxyCICD.getRevisionInfo(workspace.selection);
|
||||
ctrl.revision = revisionInfo.revision;
|
||||
ctrl.revisionStatus = revisionInfo.revisionStatus;
|
||||
} else {
|
||||
entaxyCICDService.executeOperation('readApplicationVersionLastAndInstalledRevision',
|
||||
[ctrl.storage, ctrl.application, ctrl.version])
|
||||
.then(result => {
|
||||
let revisionsInfo = JSON.parse(result);
|
||||
ctrl.lastRevision = revisionsInfo.lastRevision;
|
||||
ctrl.installedRevision = revisionsInfo.installedRevision;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
populateVersions();
|
||||
}
|
||||
}
|
||||
|
||||
function populateVersions() {
|
||||
ctrl.versions = EntaxyCICD.getVersions(workspace.selection);
|
||||
if (ctrl.versions.length > 0) {
|
||||
ctrl.version = ctrl.versions[ctrl.versions.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.addRevision = function () {
|
||||
createRevision(-1);
|
||||
}
|
||||
|
||||
ctrl.addRevisionFromExistent = function () {
|
||||
let formFields = [
|
||||
{
|
||||
label: 'Prototype Revision',
|
||||
name: 'prototypeRevision',
|
||||
enum: true,
|
||||
required: true,
|
||||
values: workspace.selection.children.map(revision => revision.title.split(' ')[0]),
|
||||
setFocused: true
|
||||
}
|
||||
];
|
||||
openCreateRevisionModal(formFields);
|
||||
}
|
||||
|
||||
function openCreateRevisionModal(formFields) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Create Revision',
|
||||
formFields: () => formFields
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
createRevision(...args);
|
||||
}, reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createRevision(prototypeRevision) {
|
||||
entaxyCICDService.executeOperation('createRevision',
|
||||
[ctrl.storage, ctrl.application, ctrl.version, prototypeRevision])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
entaxyCICDService.treeUpdated();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDApplicationController.$inject = ['workspace', '$uibModal', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdApplicationManagementButtons', {
|
||||
bindings: {
|
||||
storage: '<',
|
||||
application: '<',
|
||||
version: '<',
|
||||
revision: '<',
|
||||
revisionStatus: '<',
|
||||
isConfigurationDirty: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<button type="button" ng-click="$ctrl.configure()"
|
||||
ng-if="!$ctrl.isInstalled && !$ctrl.isUninstalled">Configure</button>
|
||||
<button type="button" ng-click="$ctrl.deploy()"
|
||||
ng-if="!$ctrl.isInstalled && !$ctrl.isUninstalled">Deploy</button>
|
||||
<button type="button" ng-click="$ctrl.install()" ng-if="!$ctrl.isInstalled">Install</button>
|
||||
<button type="button" ng-click="$ctrl.uninstall()" ng-if="$ctrl.isInstalled">Uninstall</button>
|
||||
`,
|
||||
controller: EntaxyCICDApplicationManagementButtonsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDApplicationManagementButtonsController(workspace, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.isConfigured = ctrl.revisionStatus === EntaxyCICD.REVISION_STATUS.CONFIGURED;
|
||||
ctrl.isDeployed = ctrl.revisionStatus === EntaxyCICD.REVISION_STATUS.DEPLOYED;
|
||||
ctrl.isInstalled = ctrl.revisionStatus === EntaxyCICD.REVISION_STATUS.INSTALLED;
|
||||
ctrl.isUninstalled = ctrl.revisionStatus === EntaxyCICD.REVISION_STATUS.UNINSTALLED;
|
||||
}
|
||||
|
||||
const OPERATION_TYPE = {
|
||||
CONFIGURE: 'configure',
|
||||
DEPLOY: 'deploy',
|
||||
INSTALL: 'install',
|
||||
UNINSTALL: 'uninstall'
|
||||
}
|
||||
|
||||
ctrl.configure = function () {
|
||||
processOperation(OPERATION_TYPE.CONFIGURE);
|
||||
}
|
||||
|
||||
ctrl.deploy = function () {
|
||||
processOperation(OPERATION_TYPE.DEPLOY);
|
||||
}
|
||||
|
||||
ctrl.install = function () {
|
||||
processOperation(OPERATION_TYPE.INSTALL);
|
||||
}
|
||||
|
||||
ctrl.uninstall = function () {
|
||||
processOperation(OPERATION_TYPE.UNINSTALL);
|
||||
}
|
||||
|
||||
function processOperation(operationType) {
|
||||
if (!ctrl.isConfigurationDirty || confirm(Entaxy.CONFIRMATION.UNSAVED_CHANGES)) {
|
||||
|
||||
entaxyCICDService.executeOperation(operationType + 'Revision',
|
||||
[ctrl.storage, ctrl.application, ctrl.version, ctrl.revision])
|
||||
.then(result => {
|
||||
let message =
|
||||
operationType === OPERATION_TYPE.INSTALL || operationType === OPERATION_TYPE.UNINSTALL ?
|
||||
EntaxyCICD.capitalize(operationType) + 'ation started successfully. ' +
|
||||
'<b>Please notice that operation may take some time.</b>' : result;
|
||||
Entaxy.notification(Entaxy.NOTIFICATION_TYPE.SUCCESS, message,
|
||||
Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_SUCCESS]);
|
||||
entaxyCICDService.treeUpdated();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICDApplicationManagementButtonsController.$inject = ['workspace', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,143 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdApplications', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-content-with-title-container">
|
||||
<h2>
|
||||
Applications
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-applications-table type="Application"
|
||||
import-from-file="$ctrl.importFromFile" import-from-repository="$ctrl.importFromRepository">
|
||||
</entaxy-ci-cd-applications-table>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDApplicationsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDApplicationsController(workspace, $uibModal, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
const isStorageSelected = EntaxyCICD.isStorage(workspace.selection);
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
}
|
||||
|
||||
function getFormFields(isFromRepository) {
|
||||
let formFields = [
|
||||
{
|
||||
name: 'storage',
|
||||
label: 'Storage',
|
||||
type: 'string',
|
||||
value: isStorageSelected ? workspace.selection.title : undefined,
|
||||
enum: isStorageSelected ? undefined : true,
|
||||
values: isStorageSelected ? undefined : workspace.selection.children.map(child => child.title),
|
||||
required: true,
|
||||
readOnly: isStorageSelected ? true : undefined,
|
||||
setFocused: true
|
||||
}
|
||||
];
|
||||
if (isFromRepository) {
|
||||
formFields.push({
|
||||
name: 'mavenUrl',
|
||||
label: 'Maven Url',
|
||||
type: 'string',
|
||||
required: true
|
||||
});
|
||||
} else {
|
||||
formFields.push({
|
||||
name: 'file',
|
||||
label: 'File',
|
||||
resource: true,
|
||||
required: true
|
||||
});
|
||||
}
|
||||
return formFields;
|
||||
}
|
||||
|
||||
ctrl.importFromFile = function () {
|
||||
openModalAndProcessResults(false);
|
||||
}
|
||||
|
||||
ctrl.importFromRepository = function () {
|
||||
openModalAndProcessResults(true);
|
||||
}
|
||||
|
||||
function openModalAndProcessResults(isFromRepository) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Import Application From ' + (isFromRepository ? 'Repository' : 'File'),
|
||||
formFields: () => getFormFields(isFromRepository)
|
||||
},
|
||||
backdrop: 'static'
|
||||
})
|
||||
.result.then(args => {
|
||||
if (isFromRepository) {
|
||||
processOperation('importFromRepository', args);
|
||||
} else {
|
||||
importFromFile(args);
|
||||
}
|
||||
},
|
||||
reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function importFromFile(args) {
|
||||
let file = args[1];
|
||||
const reader = new FileReader();
|
||||
reader.readAsBinaryString(file);
|
||||
reader.onloadend = function () {
|
||||
const base64String = btoa(reader.result);
|
||||
processOperation('importFromBase64String', [args[0], base64String]);
|
||||
}
|
||||
}
|
||||
|
||||
function processOperation(operationName, properties) {
|
||||
entaxyCICDService.executeOperation(operationName, properties)
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
entaxyCICDService.treeUpdated();
|
||||
})
|
||||
.catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDApplicationsController.$inject = ['workspace', '$uibModal', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,297 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdConfiguration', {
|
||||
bindings: {
|
||||
configurationId: '<',
|
||||
configured: '<',
|
||||
isDirty: '='
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-header-container">
|
||||
<h2>
|
||||
Configuration: {{$ctrl.configurationId}}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-cicd-subtitle-info-container">
|
||||
<span>Configured Id: {{$ctrl.configuredId}}</span>
|
||||
<span>Configured Type: {{$ctrl.configuredType}}</span>
|
||||
</div>
|
||||
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<form name="entaxyObjectForm" class="form-horizontal">
|
||||
<div class="entaxy-table-with-inputs" ng-if="$ctrl.viewedItems && $ctrl.viewedItems.length > 0">
|
||||
<table datatable="ng" dt-options="$ctrl.dtOptions"
|
||||
class="table-view-container table table-striped table-bordered table-hover dataTable no-footer">
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th>Name</th>
|
||||
<th>Display Name</th>
|
||||
<th>Imported Value</th>
|
||||
<th>Local Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr role="row" ng-repeat="field in $ctrl.viewedItems">
|
||||
<td ng-class="{'red': field.isRed, 'green': field.isGreen, 'bold': field.importedValue !== field.originValue}">
|
||||
{{ field.name }}
|
||||
</td>
|
||||
<td>{{ field.displayName }}</td>
|
||||
<td class="field-input-cell" ng-class="{'field-input-checkbox-cell': field.type === 'checkbox'}"
|
||||
ng-if="$ctrl.configured">
|
||||
<input type="{{field.type}}" ng-class="{'form-control': field.type !== 'checkbox'}"
|
||||
ng-model="field.importedValue" ng-change="$ctrl.checkDirtiness()"/>
|
||||
</td>
|
||||
<td ng-if="!$ctrl.configured">{{ field.importedValue }}</td>
|
||||
<td>{{ field.localValue }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
<pf-empty-state ng-if="!$ctrl.viewedItems || $ctrl.viewedItems.length == 0"></pf-empty-state>
|
||||
`,
|
||||
controller: EntaxyCICDConfigurationController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDConfigurationController(workspace, $scope, $location, entaxyCICDService, entaxyService,
|
||||
entaxyHotkeysService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.dtOptions = {
|
||||
autoWidth: false,
|
||||
destroy: true,
|
||||
order: [[0, "asc"]],
|
||||
dom: "t",
|
||||
paging: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Display Name',
|
||||
placeholder: 'Filter by Display Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
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;
|
||||
} else if (filter.id === 'displayName') {
|
||||
match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.checkDirtiness = function () {
|
||||
if ($scope.entaxyObjectForm.$dirty) {
|
||||
let isDirty = false;
|
||||
for (let i = 0; i < ctrl.items.length; i++) {
|
||||
if (ctrl.items[i].importedValue !== ctrl.items[i].originValue) {
|
||||
isDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isDirty) {
|
||||
$scope.entaxyObjectForm.$setPristine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout( function () {
|
||||
ctrl.activeTabIndex = entaxyService.getActiveTabIndex();
|
||||
});
|
||||
|
||||
$scope.$on("$locationChangeStart", function(event) {
|
||||
if ($scope.entaxyObjectForm.$dirty && !confirm(Entaxy.CONFIRMATION.UNSAVED_CHANGES)) {
|
||||
event.preventDefault();
|
||||
ctrl.isTreeOrTabSelectionUpdateNeeded = true;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('$ctrl.isTreeOrTabSelectionUpdateNeeded', function (newValue) {
|
||||
if (newValue) {
|
||||
setTimeout(function () {
|
||||
entaxyService.updateTabSelection(ctrl.activeTabIndex);
|
||||
});
|
||||
Jmx.updateTreeSelectionFromURL($location, $(entaxyCICDTreeElementId));
|
||||
ctrl.isTreeOrTabSelectionUpdateNeeded = false;
|
||||
}
|
||||
});
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
entaxyHotkeysService.setHotkeys($scope, getHotkeysConfigs());
|
||||
|
||||
if (ctrl.configured) {
|
||||
let primaryActions = [
|
||||
{ name: 'Clear Changes', actionFn: clearChanges },
|
||||
{ name: 'Copy Local Values', actionFn: useLocalValues },
|
||||
{ name: 'Save Changes', actionFn: save }
|
||||
];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
const version = EntaxyCICD.getVersion(workspace.selection);
|
||||
const revision = workspace.selection.title.split(' ')[0];
|
||||
|
||||
$scope.$watch('entaxyObjectForm.$dirty', function () {
|
||||
ctrl.isDirty = $scope.entaxyObjectForm.$dirty;
|
||||
});
|
||||
|
||||
$scope.$watch('$ctrl.configurationId', function () {
|
||||
$scope.entaxyObjectForm.$setPristine();
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function populateTable() {
|
||||
|
||||
entaxyCICDService.executeOperation('readRevisionConfiguration',
|
||||
[storage, application, version, revision, ctrl.configurationId])
|
||||
.then(result => {
|
||||
let config = JSON.parse(result);
|
||||
|
||||
ctrl.configuredId = config.id;
|
||||
ctrl.configuredType = config.type;
|
||||
|
||||
let fields = config.fields;
|
||||
ctrl.items = fields.length === 0 ? [] : fields.map(field => {
|
||||
field.type = Entaxy.convertToHtmlInputType(field.type);
|
||||
if (field.importedValue === "" || field.importedValue === null) {
|
||||
field.isRed = true;
|
||||
} else if (field.localValue === "" || field.localValue === null) {
|
||||
field.isGreen = true;
|
||||
}
|
||||
if (field.type === 'number') {
|
||||
field.importedValue = field.importedValue !== null ? JSON.parse(field.importedValue) : null;
|
||||
}
|
||||
field.originValue = field.importedValue;
|
||||
return field;
|
||||
});
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError('Can not read configuration: ' + error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
function clearChanges() {
|
||||
if ($scope.entaxyObjectForm.$dirty) {
|
||||
ctrl.items = ctrl.items.map(item => {
|
||||
item.importedValue = item.originValue;
|
||||
return item;
|
||||
});
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
$scope.entaxyObjectForm.$setPristine();
|
||||
}
|
||||
}
|
||||
|
||||
function useLocalValues() {
|
||||
ctrl.items = ctrl.items.map(item => {
|
||||
item.importedValue = item.localValue;
|
||||
return item;
|
||||
});
|
||||
if (!$scope.entaxyObjectForm.$dirty) {
|
||||
$scope.entaxyObjectForm.$setDirty();
|
||||
} else {
|
||||
ctrl.checkDirtiness();
|
||||
}
|
||||
}
|
||||
|
||||
function save() {
|
||||
if ($scope.entaxyObjectForm.$dirty) {
|
||||
let properties = getProperties();
|
||||
|
||||
entaxyCICDService.executeOperation('saveRevisionConfiguration',
|
||||
[storage, application, version, revision, ctrl.configurationId, properties])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
$scope.entaxyObjectForm.$setPristine();
|
||||
populateTable();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getProperties() {
|
||||
let filteredFields = ctrl.items.filter(field => field.importedValue !== field.originValue);
|
||||
|
||||
if (filteredFields && filteredFields.length > 0) {
|
||||
return filteredFields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.importedValue }), {});
|
||||
}
|
||||
}
|
||||
|
||||
function getHotkeysConfigs() {
|
||||
return [
|
||||
{
|
||||
...Entaxy.getSaveHotkeyDescription(),
|
||||
callback: function (event) {
|
||||
event.preventDefault();
|
||||
save();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
EntaxyCICDConfigurationController.$inject = ['workspace', '$scope', '$location', 'entaxyCICDService',
|
||||
'entaxyService', 'entaxyHotkeysService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,189 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdConfigurations', {
|
||||
bindings: {
|
||||
changeSelection: '<',
|
||||
configured: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<div class="entaxy-cicd-objects-table-container">
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDConfigurationsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDConfigurationsController(workspace, $q, entaxyCICDService, $templateCache, $route) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id'
|
||||
};
|
||||
|
||||
function changeSelected(item) {
|
||||
if (ctrl.selected[item.id]) {
|
||||
delete ctrl.selected[item.id];
|
||||
} else {
|
||||
ctrl.selected[item.id] = item;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'id',
|
||||
title: 'Id',
|
||||
placeholder: 'Filter by Id...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{
|
||||
header: 'Id',
|
||||
itemField: 'id',
|
||||
htmlTemplate: 'configurations/id.html',
|
||||
colActionFn: (configurationId) => ctrl.changeSelection(configurationId)
|
||||
},
|
||||
{ header: 'Location', itemField: 'location' }
|
||||
];
|
||||
|
||||
$templateCache.put(
|
||||
'configurations/id.html',
|
||||
'<a href="" ng-click="$ctrl.handleColAction(key, value)">{{value}}</a>'
|
||||
);
|
||||
|
||||
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 === 'id') {
|
||||
match = item.id.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.tableConfig.showCheckboxes = ctrl.configured;
|
||||
|
||||
if (ctrl.configured) {
|
||||
ctrl.selected = {};
|
||||
ctrl.tableConfig.onCheckBoxChange = (item) => changeSelected(item);
|
||||
|
||||
let primaryActions = [
|
||||
{name: 'Set Local Values', actionFn: useLocalValues}
|
||||
];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
}
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
ctrl.application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
ctrl.version = EntaxyCICD.getVersion(workspace.selection);
|
||||
ctrl.revision = workspace.selection.title.split(' ')[0];
|
||||
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
entaxyCICDService.executeOperation('listRevisionConfigurations',
|
||||
[ctrl.storage, ctrl.application, ctrl.version, ctrl.revision])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
|
||||
function useLocalValues() {
|
||||
let selectedIds = Object.keys(ctrl.selected);
|
||||
if (selectedIds.length > 0) {
|
||||
let promises = [];
|
||||
let failedIds = [];
|
||||
selectedIds.forEach(id => {
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation('fillInRevisionConfigurationWithLocalValues',
|
||||
[ctrl.storage, ctrl.application, ctrl.version, ctrl.revision, id])
|
||||
.catch(error => {
|
||||
failedIds.push(id);
|
||||
EntaxyCICD.log.error(error);
|
||||
})
|
||||
);
|
||||
});
|
||||
$q.all(promises).then(result => {
|
||||
if (failedIds.length > 0) {
|
||||
let result = selectedIds.map(id => {
|
||||
return {
|
||||
id: id,
|
||||
failed: failedIds.includes(id)
|
||||
};
|
||||
});
|
||||
let tableHtml = Entaxy.createStatusResultTable(result, 'Configuration Id');
|
||||
let mainMessage = 'Some configurations were skipped ' +
|
||||
'while setting local values due to errors that have occurred';
|
||||
Entaxy.notificationWithDetails(Entaxy.NOTIFICATION_TYPE.WARNING, mainMessage, tableHtml,
|
||||
Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_TABLE]);
|
||||
} else {
|
||||
Entaxy.notificationSuccess('Values of selected configurations were successfully ' +
|
||||
'set to values of local configurations');
|
||||
}
|
||||
$route.reload();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICDConfigurationsController.$inject = ['workspace', '$q', 'entaxyCICDService', '$templateCache', '$route'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,151 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdApplicationItems', {
|
||||
bindings: {
|
||||
version: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<pf-table-view class="entaxy-cicd-table"
|
||||
config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
`,
|
||||
controller: EntaxyCICDApplicationItemsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDApplicationItemsController(workspace, $scope, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'id',
|
||||
title: 'Id',
|
||||
placeholder: 'Filter by Id...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'revisionable',
|
||||
title: 'Revisionable',
|
||||
placeholder: 'Filter by Revisionable...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
},
|
||||
{
|
||||
id: 'editable',
|
||||
title: 'Editable',
|
||||
placeholder: 'Filter by Editable...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Id', itemField: 'id' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Revisionable', itemField: 'revisionable',
|
||||
templateFn: (value) => EntaxyCICD.getStatusTemplate(value) },
|
||||
{ header: 'Editable', itemField: 'editable',
|
||||
templateFn: (value) => EntaxyCICD.getStatusTemplate(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) {
|
||||
let match = true;
|
||||
if (filter.id === 'id') {
|
||||
match = item.id.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type === filter.value;
|
||||
} else if (filter.id === 'revisionable') {
|
||||
match = filter.value === 'yes' ? item.revisionable === true : item.revisionable === false;
|
||||
} else if (filter.id === 'editable') {
|
||||
match = filter.value === 'yes' ? item.editable === true : item.editable === false;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
entaxyCICDService.setTypesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.version', function () {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function populateTable() {
|
||||
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
|
||||
entaxyCICDService.executeOperation('listApplicationItems', [storage, application, ctrl.version])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDApplicationItemsController.$inject = ['workspace', '$scope', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,95 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdRevision', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-zero-revision-note" ng-if="$ctrl.revision === '0'">
|
||||
<entaxy-form-field-extra-info type="'info'" message="$ctrl.zeroRevisionNote"></entaxy-form-field-extra-info>
|
||||
</div>
|
||||
<div class="entaxy-cicd-header-container">
|
||||
<div class="entaxy-cicd-title-with-info-container">
|
||||
<span class="first">Application: {{$ctrl.application}}</span>
|
||||
<span>Version: {{$ctrl.version}}</span>
|
||||
<span class="lead">Revision: {{$ctrl.revision}}</span>
|
||||
<span>Revision Status: {{$ctrl.revisionStatus}}</span>
|
||||
</div>
|
||||
<div class="entaxy-cicd-header-buttons-container">
|
||||
<entaxy-ci-cd-application-management-buttons storage="$ctrl.storage" application="$ctrl.application"
|
||||
version="$ctrl.version" revision="$ctrl.revision" revision-status="$ctrl.revisionStatus"
|
||||
is-configuration-dirty="$ctrl.isConfigurationDirty">
|
||||
</entaxy-ci-cd-application-management-buttons>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-cicd-content-container">
|
||||
<h2 class="first">
|
||||
Configurations
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-configurations change-selection="$ctrl.changeSelection"
|
||||
configured="$ctrl.isConfigured"></entaxy-ci-cd-configurations>
|
||||
|
||||
<div class="entaxy-cicd-configuration-container" ng-if="$ctrl.configuration">
|
||||
|
||||
<entaxy-ci-cd-configuration configuration-id="$ctrl.configuration"
|
||||
configured="$ctrl.isConfigured" is-dirty="$ctrl.isConfigurationDirty"></entaxy-ci-cd-configuration>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDRevisionController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDRevisionController(workspace) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.zeroRevisionNote = 'Revision 0 cannot be configured';
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
ctrl.application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
ctrl.version = EntaxyCICD.getVersion(workspace.selection);
|
||||
|
||||
let revisionInfo = EntaxyCICD.getRevisionInfo(workspace.selection);
|
||||
ctrl.revision = revisionInfo.revision;
|
||||
ctrl.revisionStatus = revisionInfo.revisionStatus;
|
||||
ctrl.isConfigured = ctrl.revisionStatus === EntaxyCICD.REVISION_STATUS.CONFIGURED;
|
||||
}
|
||||
|
||||
ctrl.changeSelection = function (configurationId) {
|
||||
if (!ctrl.isConfigurationDirty || confirm(Entaxy.CONFIRMATION.UNSAVED_CHANGES)) {
|
||||
ctrl.configuration = configurationId;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICDRevisionController.$inject = ['workspace'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,181 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdVersionsRevisionsInfo', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-content-with-title-container">
|
||||
<h2>Versions & Revisions</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>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDVersionsRevisionsInfoController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDVersionsRevisionsInfoController(workspace, entaxyCICDService, $q, $templateCache, $location) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'version',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'version',
|
||||
title: 'Version',
|
||||
placeholder: 'Filter by Version...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'installedRevision',
|
||||
title: 'Installed Revision Presence',
|
||||
placeholder: 'Filter by Installed Revision Presence...',
|
||||
filterType: 'select',
|
||||
filterValues: ['present', 'not present']
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{
|
||||
header: 'Version',
|
||||
itemField: 'version',
|
||||
htmlTemplate: 'application/version.html',
|
||||
colActionFn: (version) => ctrl.changeLocation(version)
|
||||
},
|
||||
{ header: 'Last Revision', itemField: 'lastRevision' },
|
||||
{ header: 'Installed Revision', itemField: 'installedRevision' }
|
||||
];
|
||||
|
||||
$templateCache.put(
|
||||
'application/version.html',
|
||||
'<a href="" ng-click="$ctrl.handleColAction(key, value)">{{value}}</a>'
|
||||
);
|
||||
|
||||
ctrl.changeLocation = function (version) {
|
||||
let nid = $location.search().nid;
|
||||
$location.search('nid', nid + '-' + version);
|
||||
}
|
||||
|
||||
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 === 'version') {
|
||||
match = item.version.match(filter.value) !== null;
|
||||
} else if (filter.id === 'installedRevision') {
|
||||
match = filter.value === 'present' ? item.installedRevision !== '-' : item.installedRevision === '-';
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Remove Version', title: 'Remove Version', actionFn: removeVersion }
|
||||
];
|
||||
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
|
||||
const applicationFolder = workspace.selection;
|
||||
|
||||
let items = [];
|
||||
let promises = [];
|
||||
if (applicationFolder.children && applicationFolder.children.length > 0) {
|
||||
applicationFolder.children.forEach(versionFolder => {
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation('readApplicationVersionLastAndInstalledRevision',
|
||||
[ctrl.storage, applicationFolder.title, versionFolder.title])
|
||||
.then(result => {
|
||||
let revisionsInfo = JSON.parse(result);
|
||||
items.push({
|
||||
version: versionFolder.title,
|
||||
lastRevision: revisionsInfo.lastRevision,
|
||||
installedRevision: revisionsInfo.installedRevision
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
$q.all(promises).then(() => {
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
|
||||
function removeVersion(action, item) {
|
||||
let application = workspace.selection.title;
|
||||
|
||||
if (ctrl.items.length > 1) {
|
||||
let properties = [ctrl.storage, application, item.version];
|
||||
entaxyCICDService.removeItemWithConfirmation(EntaxyCICD.ITEM_TYPE.VERSION, item.version, properties);
|
||||
} else {
|
||||
let properties = [ctrl.storage, application];
|
||||
let message = 'Removing the last version of the application will lead to removing the application. ' +
|
||||
'Do you want to proceed?';
|
||||
entaxyCICDService.removeItemWithConfirmation(EntaxyCICD.ITEM_TYPE.APPLICATION, null, properties,
|
||||
false, message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
EntaxyCICDVersionsRevisionsInfoController.$inject = ['workspace', 'entaxyCICDService', '$q', '$templateCache',
|
||||
'$location'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,280 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdApplicationsTable', {
|
||||
bindings: {
|
||||
type: '@',
|
||||
importFromFile: '<',
|
||||
importFromRepository: '<',
|
||||
createProject: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig">
|
||||
<actions>
|
||||
<span class="dropdown primary-action" uib-dropdown>
|
||||
<button class="btn btn-default dropdown-toggle" uib-dropdown-toggle type="button">
|
||||
Import
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li role="menuitem" ng-click="$ctrl.importFromFile()">
|
||||
<a class="secondary-action">Import From File</a>
|
||||
</li>
|
||||
<li role="menuitem" ng-click="$ctrl.importFromRepository()">
|
||||
<a class="secondary-action">Import From Repository</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</actions>
|
||||
</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: EntaxyCICDApplicationsTableController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDApplicationsTableController(workspace, $uibModal, entaxyCICDService, $templateCache, $location) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
const isStorageSelected = EntaxyCICD.isStorage(workspace.selection);
|
||||
|
||||
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: 'applications/table/name.html',
|
||||
colActionFn: (name) => ctrl.changeLocation(name)
|
||||
}
|
||||
];
|
||||
|
||||
$templateCache.put(
|
||||
'applications/table/name.html',
|
||||
'<a href="" ng-click="$ctrl.handleColAction(key, value)">{{value}}</a>'
|
||||
);
|
||||
|
||||
ctrl.changeLocation = function (name) {
|
||||
let nid = $location.search().nid;
|
||||
if (isStorageSelected) {
|
||||
$location.search('nid', nid + '-' + name);
|
||||
} else {
|
||||
let item = ctrl.viewedItems.find(viewedItem => viewedItem.name === name);
|
||||
$location.search('nid', [nid, item.storage, name].join('-'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStorageSelected) {
|
||||
ctrl.tableColumns.push({ header: 'Storage', itemField: 'storage' });
|
||||
|
||||
ctrl.toolbarConfig.filterConfig.fields.push({
|
||||
id: 'storage',
|
||||
title: 'Storage',
|
||||
placeholder: 'Filter by Storage...',
|
||||
filterType: 'select',
|
||||
filterValues: EntaxyCICD.getStorages(workspace.selection)
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
} else if (filter.id === 'storage') {
|
||||
match = item.storage === filter.value;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
populateTable();
|
||||
|
||||
if (ctrl.type === EntaxyCICD.ITEM_TYPE.APPLICATION) {
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
actionsInclude: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns.push({
|
||||
header: 'Versions & Revisions',
|
||||
itemField: 'versionsRevisionsInfo',
|
||||
templateFn: (value) => getVersionsRevisionsColumnTemplate(value)
|
||||
});
|
||||
|
||||
} else if (ctrl.type === EntaxyCICD.ITEM_TYPE.PROJECT) {
|
||||
let primaryActions = [{name: 'Create ' + ctrl.type, actionFn: () => ctrl.createProject(ctrl.items)}];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions
|
||||
};
|
||||
}
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Remove', title: 'Remove ' + ctrl.type, actionFn: removeItem }
|
||||
];
|
||||
}
|
||||
|
||||
function getVersionsRevisionsColumnTemplate(value) {
|
||||
const DIV = {
|
||||
OPEN: '<div>',
|
||||
CLOSE: '</div>'
|
||||
};
|
||||
const CLASS_INSTALLED = 'class="entaxy-cicd-installed"';
|
||||
function insert(string, index, substring) {
|
||||
return string.slice(0, index) + substring + string.slice(index);
|
||||
}
|
||||
const spanOpen = '<span data-toggle="tooltip" title="">';
|
||||
const SPAN = {
|
||||
OPEN: {
|
||||
VERSION: insert(spanOpen, -2, 'Version'),
|
||||
LAST_REVISION: insert(spanOpen, -2, 'Last Revision'),
|
||||
INSTALLED_REVISION: insert(spanOpen, -2, 'Installed Revision')
|
||||
},
|
||||
CLOSE: '</span>'
|
||||
};
|
||||
let result = DIV.OPEN;
|
||||
value = value.sort(Entaxy.compareBy('version'));
|
||||
value.forEach(item => {
|
||||
const versionOpeningSpan = item.installedRevision !== '-' ?
|
||||
insert(SPAN.OPEN.VERSION, 5, ' ' + CLASS_INSTALLED) :
|
||||
SPAN.OPEN.VERSION;
|
||||
const revisionOpeningSpan = item.installedRevision !== '-' ?
|
||||
insert(SPAN.OPEN.INSTALLED_REVISION, 5, ' ' + CLASS_INSTALLED) :
|
||||
SPAN.OPEN.INSTALLED_REVISION;
|
||||
|
||||
result = result +
|
||||
DIV.OPEN +
|
||||
versionOpeningSpan + item.version + SPAN.CLOSE +
|
||||
SPAN.OPEN.LAST_REVISION + item.lastRevision + SPAN.CLOSE +
|
||||
revisionOpeningSpan + item.installedRevision + SPAN.CLOSE +
|
||||
DIV.CLOSE;
|
||||
});
|
||||
return result + DIV.CLOSE;
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
|
||||
let items = [];
|
||||
|
||||
if (isStorageSelected) {
|
||||
items = getItemsFromChildren(workspace.selection);
|
||||
} else {
|
||||
let storages = workspace.selection.children;
|
||||
if (storages && storages.length > 0) {
|
||||
storages.forEach(storage => {
|
||||
items = getItemsFromChildren(storage);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrl.type === EntaxyCICD.ITEM_TYPE.APPLICATION) {
|
||||
items.forEach(item => {
|
||||
if (item.versions) {
|
||||
item.versionsRevisionsInfo = [];
|
||||
item.versions.forEach(version => {
|
||||
entaxyCICDService.executeOperation('readApplicationVersionLastAndInstalledRevision',
|
||||
[item.storage, item.name, version])
|
||||
.then(result => {
|
||||
let revisionsInfo = JSON.parse(result);
|
||||
item.versionsRevisionsInfo.push({
|
||||
version: version,
|
||||
lastRevision: revisionsInfo.lastRevision,
|
||||
installedRevision: revisionsInfo.installedRevision
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
}
|
||||
|
||||
function getItemsFromChildren(selection) {
|
||||
let items = [];
|
||||
if (selection.children && selection.children.length > 0) {
|
||||
selection.children.forEach(item => {
|
||||
items.push({
|
||||
name: item.title,
|
||||
storage: selection.title,
|
||||
versions: ctrl.type === EntaxyCICD.ITEM_TYPE.APPLICATION
|
||||
&& item.children && item.children.length > 0 ?
|
||||
item.children.map(child => child.title) : undefined
|
||||
});
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
function removeItem(action, item) {
|
||||
let properties = [item.storage, item.name];
|
||||
entaxyCICDService.removeItemWithConfirmation(ctrl.type, item.name, properties, true);
|
||||
}
|
||||
}
|
||||
EntaxyCICDApplicationsTableController.$inject = ['workspace', '$uibModal', 'entaxyCICDService',
|
||||
'$templateCache', '$location'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdContents', {
|
||||
template:
|
||||
`
|
||||
<div class="contents" ng-view ng-if="$ctrl.isReady" style="padding: 0 !important;"></div>
|
||||
`,
|
||||
controller: EntaxyCICDContentsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDContentsController($scope, $route) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
ctrl.isReady = false;
|
||||
|
||||
$scope.$on('jmxTreeClicked', function () {
|
||||
ctrl.isReady = true;
|
||||
$route.reload();
|
||||
});
|
||||
}
|
||||
EntaxyCICDContentsController.$inject = ['$scope', '$route'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,237 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD.log.debug("loading navigation");
|
||||
|
||||
EntaxyCICD._module
|
||||
.config(configureRoutes)
|
||||
.component('entaxyCiCdNavigation', {
|
||||
template: `<hawtio-tabs tabs="$ctrl.tabs" on-change="$ctrl.goto(tab)"></hawtio-tabs>`,
|
||||
controller: EntaxyCICDNavigationController
|
||||
})
|
||||
.name;
|
||||
EntaxyCICD.log.debug("loaded navigation " + EntaxyCICD.navigationModule);
|
||||
|
||||
function EntaxyCICDNavigationController($scope, $location, workspace, localStorage, jolokia, $rootScope) {
|
||||
'ngInject';
|
||||
let ctrl = this;
|
||||
this.$location = $location;
|
||||
let selected = workspace.selection;
|
||||
entaxyCICDJmxDomain = localStorage['entaxyCICDJmxDomain'] || "ru.entaxy.cicd";
|
||||
|
||||
$scope.$on('jmxTreeClicked', function (event, selectedNode) {
|
||||
ctrl.tabs = getTabs();
|
||||
let tab;
|
||||
if (!selected) {
|
||||
selected = selectedNode;
|
||||
tab = _.find(ctrl.tabs, { path: ctrl.$location.path() });
|
||||
if (!tab) {
|
||||
tab = ctrl.tabs[0];
|
||||
}
|
||||
} else {
|
||||
if (JSON.stringify(selected.folderNames) !== JSON.stringify(selectedNode.folderNames)) {
|
||||
selected = selectedNode;
|
||||
tab = ctrl.tabs[0];
|
||||
} else {
|
||||
tab = _.find(ctrl.tabs, {path: ctrl.$location.path()});
|
||||
if (!tab) {
|
||||
tab = ctrl.tabs[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
ctrl.$location.path(tab.path);
|
||||
});
|
||||
|
||||
EntaxyCICDNavigationController.prototype.$onInit = function () {
|
||||
if (!workspace.selection) {
|
||||
this.tabs = [];
|
||||
} else {
|
||||
this.tabs = getTabs();
|
||||
}
|
||||
};
|
||||
|
||||
EntaxyCICDNavigationController.prototype.goto = function (tab) {
|
||||
this.$location.path(tab.path);
|
||||
};
|
||||
|
||||
function getTabs() {
|
||||
|
||||
var tabs = [];
|
||||
var enabledRoutes = Object.keys(TAB_CONFIG)
|
||||
.map(function (config) { return TAB_CONFIG[config].route; })
|
||||
.filter(function (route) { return _.startsWith(route, '/entaxy-cicd'); });
|
||||
if (enabledRoutes.length > 0) {
|
||||
if (workspace.getSelectedMBeanName()) {
|
||||
if (workspace.hasDomainAndProperties(entaxyCICDJmxDomain, { module: 'projects' })) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.projects.title, TAB_CONFIG.projects.route));
|
||||
} else if (workspace.hasDomainAndProperties(entaxyCICDJmxDomain, { module: 'applications' })) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.applications.title, TAB_CONFIG.applications.route));
|
||||
}
|
||||
} else if (shouldShowProjectsTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.projects.title, TAB_CONFIG.projects.route));
|
||||
} else if (shouldShowVersionsTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.projectVersions.title, TAB_CONFIG.projectVersions.route));
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.project.title, TAB_CONFIG.project.route));
|
||||
} else if (shouldShowProjectTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.project.title, TAB_CONFIG.project.route));
|
||||
} else if (shouldShowBuildInfoTabs()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.buildInfoItems.title, TAB_CONFIG.buildInfoItems.route));
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.buildInfoRequirements.title, TAB_CONFIG.buildInfoRequirements.route));
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.buildInfoComponents.title, TAB_CONFIG.buildInfoComponents.route));
|
||||
} else if (shouldShowApplicationsTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.applications.title, TAB_CONFIG.applications.route));
|
||||
} else if (shouldShowVersionsRevisionsTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.versionsRevisionsInfo.title, TAB_CONFIG.versionsRevisionsInfo.route));
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.application.title, TAB_CONFIG.application.route));
|
||||
} else if (shouldShowApplicationTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.application.title, TAB_CONFIG.application.route));
|
||||
} else if (shouldShowRevisionTab()) {
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.revision.title, TAB_CONFIG.revision.route));
|
||||
tabs.push(new Nav.HawtioTab(TAB_CONFIG.application.title, TAB_CONFIG.application.route));
|
||||
}
|
||||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
function shouldShowProjectsTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'projects' &&
|
||||
(selectionFolderNames.length === 2 || selectionFolderNames.length === 3);
|
||||
}
|
||||
|
||||
function shouldShowVersionsTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'projects' && selectionFolderNames.length === 4;
|
||||
}
|
||||
|
||||
function shouldShowProjectTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'projects' &&
|
||||
(selectionFolderNames.length === 4 || selectionFolderNames.length === 5);
|
||||
}
|
||||
|
||||
function shouldShowBuildInfoTabs() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'projects' && selectionFolderNames.length === 6;
|
||||
}
|
||||
|
||||
function shouldShowApplicationsTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'applications' &&
|
||||
(selectionFolderNames.length === 2 || selectionFolderNames.length === 3);
|
||||
}
|
||||
|
||||
function shouldShowApplicationTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'applications' && selectionFolderNames.length === 5;
|
||||
}
|
||||
|
||||
function shouldShowVersionsRevisionsTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'applications' && selectionFolderNames.length === 4;
|
||||
}
|
||||
|
||||
function shouldShowRevisionTab() {
|
||||
let selectionFolderNames = workspace.selection.folderNames;
|
||||
return selectionFolderNames[1] === 'applications' && selectionFolderNames.length === 6;
|
||||
}
|
||||
|
||||
// global event for entaxy extras
|
||||
$rootScope.$emit('entaxyCiCdNavigationInited', $scope);
|
||||
}
|
||||
EntaxyCICDNavigationController.$inject = ['$scope', '$location', 'workspace', 'localStorage', 'jolokia', '$rootScope']
|
||||
|
||||
function configureRoutes($routeProvider) {
|
||||
$routeProvider.
|
||||
when(TAB_CONFIG.projects.route,
|
||||
{ template: '<entaxy-ci-cd-projects></entaxy-ci-cd-projects>' }).
|
||||
when(TAB_CONFIG.projectVersions.route,
|
||||
{ template: '<entaxy-ci-cd-project-versions></entaxy-ci-cd-project-versions>' }).
|
||||
when(TAB_CONFIG.project.route,
|
||||
{ template: '<entaxy-ci-cd-project></entaxy-ci-cd-project>' }).
|
||||
when(TAB_CONFIG.buildInfoItems.route,
|
||||
{ template: '<entaxy-ci-cd-build-info type="Items"></entaxy-ci-cd-build-info>' }).
|
||||
when(TAB_CONFIG.buildInfoRequirements.route,
|
||||
{ template: '<entaxy-ci-cd-build-info type="Requirements"></entaxy-ci-cd-build-info>' }).
|
||||
when(TAB_CONFIG.buildInfoComponents.route,
|
||||
{ template: '<entaxy-ci-cd-build-info type="Components"></entaxy-ci-cd-build-info>' }).
|
||||
when(TAB_CONFIG.applications.route,
|
||||
{ template: '<entaxy-ci-cd-applications></entaxy-ci-cd-applications>' }).
|
||||
when(TAB_CONFIG.application.route,
|
||||
{ template: '<entaxy-ci-cd-application></entaxy-ci-cd-application>' }).
|
||||
when(TAB_CONFIG.versionsRevisionsInfo.route,
|
||||
{ template: '<entaxy-ci-cd-versions-revisions-info></entaxy-ci-cd-versions-revisions-info>' }).
|
||||
when(TAB_CONFIG.revision.route,
|
||||
{ template: '<entaxy-ci-cd-revision></entaxy-ci-cd-revision>' });
|
||||
}
|
||||
configureRoutes.$inject = ['$routeProvider'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
||||
|
||||
let TAB_CONFIG = {
|
||||
projects: {
|
||||
title: 'Projects',
|
||||
route: '/entaxy-cicd/projects'
|
||||
},
|
||||
project: {
|
||||
title: 'Project',
|
||||
route: '/entaxy-cicd/project'
|
||||
},
|
||||
projectVersions: {
|
||||
title: 'Versions',
|
||||
route: '/entaxy-cicd/project/versions'
|
||||
},
|
||||
buildInfoItems: {
|
||||
title: 'Items',
|
||||
route: '/entaxy-cicd/project/build-info/items'
|
||||
},
|
||||
buildInfoRequirements: {
|
||||
title: 'Requirements',
|
||||
route: '/entaxy-cicd/project/build-info/requirements'
|
||||
},
|
||||
buildInfoComponents: {
|
||||
title: 'Components',
|
||||
route: '/entaxy-cicd/project/build-info/components'
|
||||
},
|
||||
applications: {
|
||||
title: 'Applications',
|
||||
route: '/entaxy-cicd/applications'
|
||||
},
|
||||
application: {
|
||||
title: 'Application',
|
||||
route: '/entaxy-cicd/application'
|
||||
},
|
||||
versionsRevisionsInfo: {
|
||||
title: 'Versions & Revisions',
|
||||
route: '/entaxy-cicd/application/versions-revisions-info'
|
||||
},
|
||||
revision: {
|
||||
title: 'Revision',
|
||||
route: '/entaxy-cicd/application/revision'
|
||||
}
|
||||
};
|
@ -0,0 +1,110 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdAddObjectsModal', {
|
||||
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">
|
||||
<div ng-if="$ctrl.resolve.objects">
|
||||
<div class="add-objects-message-container">
|
||||
{{$ctrl.message}}
|
||||
</div>
|
||||
<entaxy-expandable-list items="$ctrl.resolve.objects" use-toolbar="false" show-select-box="true"
|
||||
on-check-box-change-fn="$ctrl.changeSelected">
|
||||
</entaxy-expandable-list>
|
||||
</div>
|
||||
<entaxy-ci-cd-objects-select change-selected="$ctrl.changeSelected" ng-if="!$ctrl.resolve.objects"
|
||||
excluded-object-ids="$ctrl.resolve.excludedObjectIds"></entaxy-ci-cd-objects-select>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="$ctrl.cancel()"
|
||||
ng-if="$ctrl.includeSkip">Skip</button>
|
||||
<button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyCICDAddObjectsModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCICDAddObjectsModalController() {
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
ctrl.modalTitle = 'Add Objects to the Project: ' + ctrl.resolve.project;
|
||||
|
||||
ctrl.selected = {};
|
||||
|
||||
if (ctrl.resolve.objects) {
|
||||
ctrl.message = 'You may also want to add optional related objects:';
|
||||
ctrl.includeSkip = true;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.changeSelected = function (item) {
|
||||
|
||||
if (ctrl.resolve.objects) {
|
||||
if (item.relatedTo && item.relatedTo.length > 1) {
|
||||
let relatedToExcludeParent = item.relatedTo.filter(objectId => objectId !== item.parent);
|
||||
relatedToExcludeParent.forEach(objectId => {
|
||||
let object = ctrl.resolve.objects.find(it => it.name === objectId);
|
||||
let relatedObject = object.sublist.find(it => it.name === item.name);
|
||||
relatedObject.selected = item.selected;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrl.selected[item.fullId]) {
|
||||
delete ctrl.selected[item.fullId];
|
||||
} else {
|
||||
ctrl.selected[item.fullId] = item;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.save = function () {
|
||||
ctrl.modalInstance.close(ctrl.selected);
|
||||
}
|
||||
|
||||
ctrl.cancel = function(reason) {
|
||||
ctrl.modalInstance.dismiss(reason);
|
||||
}
|
||||
}
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,171 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdBuildInfo', {
|
||||
bindings: {
|
||||
type: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-header-container">
|
||||
<div class="entaxy-cicd-title-with-info-container">
|
||||
<span class="first lead">Build</span>
|
||||
<span>Project: {{$ctrl.project}}</span>
|
||||
<span>Version: {{$ctrl.version}}</span>
|
||||
<div ng-if="$ctrl.mavenUrl">
|
||||
<span>Maven URL: {{$ctrl.mavenUrl}}</span>
|
||||
<entaxy-copy-to-clipboard-button title="Copy maven URL to clipboard"
|
||||
text-to-copy="$ctrl.mavenUrl"></entaxy-copy-to-clipboard-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entaxy-cicd-header-buttons-container">
|
||||
<div class="btn-group" uib-dropdown>
|
||||
<button id="single-button" type="button" uib-dropdown-toggle ng-disabled="disabled">
|
||||
Export
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu
|
||||
role="menu" aria-labelledby="single-button">
|
||||
<li role="menuitem"><a ng-click="$ctrl.exportToFile()">Export To File</a></li>
|
||||
<li role="menuitem"><a ng-click="$ctrl.exportToRepository()">Export To Repository</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-cicd-content-container">
|
||||
<h2 class="first">
|
||||
{{ $ctrl.type }}
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-project-items ng-if="$ctrl.isItems()"></entaxy-ci-cd-project-items>
|
||||
<entaxy-ci-cd-requirements ng-if="$ctrl.isRequirements()"
|
||||
version="$ctrl.version" type="BuiltProject"></entaxy-ci-cd-requirements>
|
||||
<entaxy-ci-cd-project-components ng-if="$ctrl.isComponents()"></entaxy-ci-cd-project-components>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyCICDBuildInfoController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCICDBuildInfoController(workspace, entaxyCICDService, entaxyService, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const TYPE = {
|
||||
ITEMS: 'Items',
|
||||
REQUIREMENTS: 'Requirements',
|
||||
COMPONENTS: 'Components'
|
||||
}
|
||||
|
||||
ctrl.isItems = function () {
|
||||
return ctrl.type === TYPE.ITEMS;
|
||||
}
|
||||
|
||||
ctrl.isRequirements = function () {
|
||||
return ctrl.type === TYPE.REQUIREMENTS;
|
||||
}
|
||||
|
||||
ctrl.isComponents = function () {
|
||||
return ctrl.type === TYPE.COMPONENTS;
|
||||
}
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.project = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
ctrl.version = EntaxyCICD.getVersion(workspace.selection);
|
||||
|
||||
entaxyCICDService.executeOperation('readMavenUrl', [storage, ctrl.project, ctrl.version])
|
||||
.then(result => {
|
||||
ctrl.mavenUrl = result;
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.exportToFile = function () {
|
||||
entaxyCICDService.executeOperation('exportToFile', [storage, ctrl.project, ctrl.version])
|
||||
.then(result => {
|
||||
let fileName = ctrl.project + '-' + ctrl.version + '.jar';
|
||||
entaxyService.downloadFileFromBase64StringContent(result, fileName);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.exportToRepository = function () {
|
||||
entaxyCICDService.executeOperation('listRepositories', [])
|
||||
.then(result => {
|
||||
let formFields = [
|
||||
{
|
||||
label: 'Repository',
|
||||
name: 'repository',
|
||||
enum: true,
|
||||
required: true,
|
||||
values: JSON.parse(result),
|
||||
setFocused: true
|
||||
}
|
||||
];
|
||||
|
||||
showExportModal(formFields);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
}
|
||||
|
||||
function showExportModal(formFields) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Export Project To Repository',
|
||||
formFields: () => formFields
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
exportToRepository(args[0]);
|
||||
}, reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function exportToRepository(repository) {
|
||||
entaxyCICDService.executeOperation('exportToRepository',
|
||||
[storage, ctrl.project, ctrl.version, repository])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
entaxyCICDBuildInfoController.$inject = ['workspace', 'entaxyCICDService', 'entaxyService', '$uibModal'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,126 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdProjectComponents', {
|
||||
template:
|
||||
`
|
||||
<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: EntaxyCICDProjectComponentsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDProjectComponentsController(workspace, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'id',
|
||||
title: 'Id',
|
||||
placeholder: 'Filter by Id...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Id', itemField: 'id' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Priority', itemField: 'priority' }
|
||||
];
|
||||
|
||||
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 === 'id') {
|
||||
match = item.id.match(filter.value) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type === filter.value;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
entaxyCICDService.setTypesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const project = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
const version = EntaxyCICD.getVersion(workspace.selection);
|
||||
|
||||
entaxyCICDService.executeOperation('listBuiltProjectComponents', [storage, project, version])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDProjectComponentsController.$inject = ['workspace', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,126 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdProjectItems', {
|
||||
template:
|
||||
`
|
||||
<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: EntaxyCICDProjectItemsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDProjectItemsController(workspace, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'id',
|
||||
title: 'Id',
|
||||
placeholder: 'Filter by Id...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Id', itemField: 'id' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Component', itemField: 'component' }
|
||||
];
|
||||
|
||||
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 === 'id') {
|
||||
match = item.id.match(filter.value) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type === filter.value;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
entaxyCICDService.setTypesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const project = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
const version = EntaxyCICD.getVersion(workspace.selection);
|
||||
|
||||
entaxyCICDService.executeOperation('listBuiltProjectItems', [storage, project, version])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDProjectItemsController.$inject = ['workspace', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,489 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdObjects', {
|
||||
bindings: {
|
||||
storage: '<',
|
||||
project: '<',
|
||||
version: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig">
|
||||
<actions>
|
||||
<button type="button" class="btn btn-default" ng-repeat="action in $ctrl.actions"
|
||||
ng-click="action.actionFn()">
|
||||
{{action.name}}
|
||||
</button>
|
||||
</actions>
|
||||
</pf-toolbar>
|
||||
<div class="entaxy-cicd-objects-table-container">
|
||||
<pf-table-view class="entaxy-cicd-table"
|
||||
config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
dt-options="$ctrl.dtOptions"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDObjectsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDObjectsController(workspace, $scope, $uibModal, entaxyCICDService, $q, $route) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id',
|
||||
onCheckBoxChange: (item) => changeSelected(item)
|
||||
};
|
||||
|
||||
function changeSelected(item) {
|
||||
if (ctrl.selected[item.id]) {
|
||||
delete ctrl.selected[item.id];
|
||||
} else {
|
||||
ctrl.selected[item.id] = item;
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Id / Name',
|
||||
placeholder: 'Filter by Id or Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
placeholder: 'Filter by Status...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'scope',
|
||||
title: 'Scope',
|
||||
placeholder: 'Filter by Scope...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'required',
|
||||
title: 'Required',
|
||||
placeholder: 'Filter by Required...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
},
|
||||
{
|
||||
id: 'ignored',
|
||||
title: 'Ignored',
|
||||
placeholder: 'Filter by Ignored...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Status', itemField: 'status', templateFn: (value) => getObjectStatusTemplate(value) },
|
||||
{ header: 'Id / Name', itemField: 'displayName' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Scope', itemField: 'scope' },
|
||||
{ header: 'Required', itemField: 'required',
|
||||
templateFn: (value) => EntaxyCICD.getStatusTemplate(value) },
|
||||
{ header: 'Ignored', itemField: 'ignored',
|
||||
templateFn: (value) => EntaxyCICD.getStatusTemplate(value) },
|
||||
{ header: 'Id', itemField: 'id' }
|
||||
];
|
||||
|
||||
function getObjectStatusTemplate(value) {
|
||||
switch (value) {
|
||||
case 'INCLUDED':
|
||||
return '<span class="pficon pficon-ok" data-toggle="tooltip" title="Included"></span>';
|
||||
case 'IGNORED':
|
||||
return '<span class="pficon pficon-arrow" data-toggle="tooltip" title="Ignored"></span>';
|
||||
case 'REQUIRED':
|
||||
return '<span class="pficon pficon-warning-triangle-o" data-toggle="tooltip" title="Required"></span>';
|
||||
case 'GHOST':
|
||||
return '<span class="pficon pficon-unknowm" data-toggle="tooltip" title="Ghost"></span>';
|
||||
case 'DELETED':
|
||||
return '<span class="pficon pficon-error-circle-o" data-toggle="tooltip" title="Deleted"></span>';
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.dtOptions = {
|
||||
order: [[1, "desc"]],
|
||||
columnDefs: [
|
||||
{ "targets": [0], "sortable": false },
|
||||
{ "targets": [7], "class": "hide" }
|
||||
]
|
||||
};
|
||||
|
||||
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 === 'status') {
|
||||
match = item.status === filter.value;
|
||||
} else if (filter.id === 'displayName') {
|
||||
match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type === filter.value;
|
||||
} else if (filter.id === 'scope') {
|
||||
match = item.scope === filter.value;
|
||||
} else if (filter.id === 'required') {
|
||||
match = filter.value === 'yes' ? item.required === true : item.required === false;
|
||||
} else if (filter.id === 'ignored') {
|
||||
match = filter.value === 'yes' ? item.ignored === true : item.ignored === false;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.selected = {};
|
||||
|
||||
let primaryActions = [
|
||||
{ name: 'Add Objects', actionFn: () => ctrl.showAddObjectsModal() },
|
||||
{ name: 'Add Resources', actionFn: () => ctrl.showAddResourcesModal() }
|
||||
];
|
||||
|
||||
ctrl.toolbarConfig.actionsConfig = {
|
||||
primaryActions: primaryActions,
|
||||
actionsInclude: true
|
||||
};
|
||||
|
||||
ctrl.actions = [
|
||||
{ name: 'Include Selected', actionFn: ctrl.includeSelected },
|
||||
{ name: 'Ignore Selected', actionFn: ctrl.ignoreSelected },
|
||||
{ name: 'Remove Selected', actionFn: ctrl.removeSelected },
|
||||
{ name: 'Add Related', actionFn: ctrl.addRelatedObjects }
|
||||
];
|
||||
|
||||
entaxyCICDService.setTypesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
|
||||
entaxyCICDService.setScopesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
|
||||
let filterConfigFieldStatus = ctrl.toolbarConfig.filterConfig.fields.find(field => field.id === 'status');
|
||||
entaxyCICDService.executeOperation('readProjectItemStatuses', [])
|
||||
.then(result => {
|
||||
filterConfigFieldStatus.filterValues = JSON.parse(result);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.version', function () {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function populateTable() {
|
||||
ctrl.selected = {};
|
||||
entaxyCICDService.executeOperation('listProjectItems', [ctrl.storage, ctrl.project, ctrl.version])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items.map(item => {
|
||||
if (!item.displayName || item.displayName.trim().length == 0) {
|
||||
item.displayName = item.id;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.showAddObjectsModal = function (objects) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdAddObjectsModal',
|
||||
resolve: {
|
||||
project: () => ctrl.project,
|
||||
objects: () => objects,
|
||||
excludedObjectIds: () => ctrl.items.length > 0 ? ctrl.items.map(item => item.id) : []
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static'
|
||||
})
|
||||
.result.then(objectsMap => {
|
||||
addObjects(objectsMap);
|
||||
},
|
||||
reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addObjects(objectsMap) {
|
||||
let objectsIds = Object.keys(objectsMap);
|
||||
if (objectsIds.length > 0) {
|
||||
let promises = [];
|
||||
objectsIds.forEach(objectId => {
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation('addObject',
|
||||
[ctrl.storage, ctrl.project, ctrl.version, objectId])
|
||||
);
|
||||
});
|
||||
$q.all(promises).then(result => {
|
||||
addRelatedObjects(objectsMap, objectsIds, result);
|
||||
|
||||
Entaxy.notificationSuccess('Operation Succeeded');
|
||||
populateTable();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addRelatedObjects(objectsMap, objectsIds, result, showNotification) {
|
||||
let objectsTree = [];
|
||||
let relations = {};
|
||||
let addedItems = ctrl.items.length > 0 ? ctrl.items.map(item => item.id) : [];
|
||||
for (let i = 0; i < objectsIds.length; i++) {
|
||||
let relatedObjects = JSON.parse(result[i]);
|
||||
if (relatedObjects.length > 0) {
|
||||
let objectsToAdd = relatedObjects.filter(object =>
|
||||
!objectsIds.includes(object.fullId) && !addedItems.includes(object.fullId));
|
||||
|
||||
if (objectsToAdd.length > 0) {
|
||||
let sublist = objectsToAdd.map(object => {
|
||||
addRelation(relations, object.fullId, objectsIds[i]);
|
||||
|
||||
return {
|
||||
name: object.fullId,
|
||||
fullId: object.fullId,
|
||||
displayName: object.displayName,
|
||||
additionalInfo: object.type,
|
||||
parent: objectsIds[i],
|
||||
disableRowExpansion: true
|
||||
};
|
||||
});
|
||||
objectsTree.push({
|
||||
name: objectsIds[i],
|
||||
displayName: objectsMap[objectsIds[i]].displayName,
|
||||
additionalInfo: objectsMap[objectsIds[i]].type,
|
||||
isExpanded: true,
|
||||
sublist: sublist.sort(Entaxy.compareBy('displayName'))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objectsTree.length > 0) {
|
||||
setRelated(relations, objectsTree);
|
||||
ctrl.showAddObjectsModal(objectsTree);
|
||||
} else {
|
||||
if (showNotification) {
|
||||
Entaxy.notificationInfo('There are no related objects that are not included');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addRelation(relations, relatedObjectId, objectId) {
|
||||
if (relations[relatedObjectId]) {
|
||||
relations[relatedObjectId].push(objectId);
|
||||
} else {
|
||||
relations[relatedObjectId] = [objectId];
|
||||
}
|
||||
}
|
||||
|
||||
function setRelated(relations, objectsTree) {
|
||||
Object.keys(relations).forEach(key => {
|
||||
if (relations[key].length > 1) {
|
||||
relations[key].forEach(objectId => {
|
||||
let object = objectsTree.find(object => object.name === objectId);
|
||||
let relatedObject = object.sublist.find(object => object.name === key);
|
||||
relatedObject.relatedTo = relations[key];
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.addRelatedObjects = function () {
|
||||
let objectsIds = Object.keys(ctrl.selected);
|
||||
if (objectsIds.length == 0) {
|
||||
Entaxy.notificationInfo('At least one item should be selected');
|
||||
return;
|
||||
}
|
||||
|
||||
let objectsMap = {};
|
||||
let promises = [];
|
||||
objectsIds.forEach(objectId => {
|
||||
if (ctrl.selected[objectId].type === 'OBJECT') {
|
||||
objectsMap[objectId] = {
|
||||
displayName: ctrl.selected[objectId].displayName,
|
||||
type: ctrl.selected[objectId].runtimeType
|
||||
};
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation('getRelatedObjects', [objectId])
|
||||
);
|
||||
}
|
||||
});
|
||||
if (promises.length > 0) {
|
||||
$q.all(promises).then(result => {
|
||||
addRelatedObjects(objectsMap, Object.keys(objectsMap), result, true);
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
});
|
||||
} else {
|
||||
Entaxy.notificationInfo('Selected items should have OBJECT type');
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.showAddResourcesModal = function () {
|
||||
$uibModal.open({
|
||||
component: 'entaxyResourceViewerModal',
|
||||
resolve: {
|
||||
config: {
|
||||
resourceProvider: 'schemas',
|
||||
folderSelectionEnabled: true,
|
||||
multipleSelectionEnabled: true,
|
||||
providersSelectionEnabled: true
|
||||
}
|
||||
},
|
||||
size: 'xl',
|
||||
backdrop: 'static'
|
||||
})
|
||||
.result.then(locations => {
|
||||
addResources(locations);
|
||||
},
|
||||
reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addResources(locations) {
|
||||
let promises = [];
|
||||
let failedResources = [];
|
||||
locations.forEach(location => {
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation('addResource',
|
||||
[ctrl.storage, ctrl.project, ctrl.version, location])
|
||||
.catch(error => {
|
||||
failedResources.push(location);
|
||||
EntaxyCICD.log.error(error);
|
||||
})
|
||||
);
|
||||
});
|
||||
$q.all(promises).then(result => {
|
||||
if (failedResources.length > 0) {
|
||||
let result = locations.map(location => {
|
||||
return {
|
||||
id: location,
|
||||
failed: failedResources.includes(location)
|
||||
};
|
||||
});
|
||||
let tableHtml = Entaxy.createStatusResultTable(result, 'Location');
|
||||
let mainMessage = 'Errors occurred while adding resources';
|
||||
Entaxy.notificationWithDetails(Entaxy.NOTIFICATION_TYPE.WARNING, mainMessage, tableHtml,
|
||||
Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_TABLE]);
|
||||
} else {
|
||||
Entaxy.notificationSuccess('Operation Succeeded');
|
||||
}
|
||||
$route.reload();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.includeSelected = function () {
|
||||
processOperationSelected('addItem', 'Selected items were successfully included into the project');
|
||||
}
|
||||
|
||||
ctrl.ignoreSelected = function () {
|
||||
processOperationSelected('ignoreItem', 'Selected items were successfully ignored from the project');
|
||||
}
|
||||
|
||||
ctrl.removeSelected = function () {
|
||||
const operationName = 'removeItems';
|
||||
const successMessage = 'Selected items were successfully removed from the project';
|
||||
let selectedIds = Object.keys(ctrl.selected);
|
||||
if (selectedIds.length > 0) {
|
||||
entaxyCICDService
|
||||
.executeOperation(operationName, [ctrl.storage, ctrl.project, ctrl.version, selectedIds])
|
||||
.then(result => {
|
||||
let unremovedItems = JSON.parse(result);
|
||||
if (unremovedItems && Object.keys(unremovedItems).length > 0) {
|
||||
let message = 'There are items that cannot be removed ' +
|
||||
'since they are required by some of remaining items';
|
||||
let table = EntaxyCICD.createTableFromUnremovedItems(unremovedItems);
|
||||
Entaxy.notificationWithDetails(Entaxy.NOTIFICATION_TYPE.INFO, message, table, 30000);
|
||||
} else {
|
||||
Entaxy.notificationSuccess(successMessage);
|
||||
}
|
||||
$route.reload();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function processOperationSelected(operationName, successMessage) {
|
||||
let selectedIds = Object.keys(ctrl.selected);
|
||||
if (selectedIds.length > 0) {
|
||||
let promises = [];
|
||||
selectedIds.forEach(id => {
|
||||
promises.push(
|
||||
entaxyCICDService.executeOperation(operationName,
|
||||
[ctrl.storage, ctrl.project, ctrl.version, id])
|
||||
);
|
||||
});
|
||||
$q.all(promises).then(result => {
|
||||
Entaxy.notificationSuccess(successMessage ? successMessage : 'Operation succeeded');
|
||||
$route.reload();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICDObjectsController.$inject = ['workspace', '$scope', '$uibModal', 'entaxyCICDService', '$q', '$route'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,127 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdObjectsSelect', {
|
||||
bindings: {
|
||||
changeSelected: '<',
|
||||
excludedObjectIds: '<'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
|
||||
<div class="entaxy-cicd-objects-table-container">
|
||||
<pf-table-view config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
dt-options="$ctrl.dtOptions"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDObjectsSelectController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDObjectsSelectController(workspace, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'fullId',
|
||||
onCheckBoxChange: (item) => ctrl.changeSelected(item)
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'displayName',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'text'
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Name', itemField: 'displayName' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Full Id', itemField: 'fullId' }
|
||||
];
|
||||
|
||||
ctrl.dtOptions = {
|
||||
columnDefs: [
|
||||
{ "targets": [0], "sortable": false },
|
||||
{ "targets": [3], "class": "hide" }
|
||||
]
|
||||
};
|
||||
|
||||
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 === 'type') {
|
||||
match = item.type.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
populateTable();
|
||||
}
|
||||
|
||||
function populateTable() {
|
||||
entaxyCICDService.executeOperation('listObjects', [])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items.filter(item => !ctrl.excludedObjectIds.includes(item.fullId));
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDObjectsSelectController.$inject = ['workspace', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,192 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdProject', {
|
||||
template:
|
||||
`
|
||||
<div ng-if="$ctrl.versions || $ctrl.isVersionSelected">
|
||||
<div class="entaxy-cicd-header-container">
|
||||
<div class="entaxy-cicd-title-with-info-container">
|
||||
<span class="first" ng-class="{'lead': !$ctrl.isVersionSelected}">Project: {{$ctrl.project}}</span>
|
||||
<span class="lead" ng-if="$ctrl.isVersionSelected">Version: {{$ctrl.version}}</span>
|
||||
<div ng-if="!$ctrl.isVersionSelected">
|
||||
<span>Version:</span>
|
||||
<entaxy-select-from-enum values="$ctrl.versions" model="$ctrl.version"
|
||||
is-empty-included="false"></entaxy-select-from-enum>
|
||||
|
||||
<div class="btn-group" uib-dropdown>
|
||||
<button id="single-button" type="button" uib-dropdown-toggle ng-disabled="disabled">
|
||||
Add Version
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
|
||||
<li role="menuitem"><a ng-click="$ctrl.addVersionFromScratch()">Add Version From Scratch</a></li>
|
||||
<li role="menuitem"><a ng-click="$ctrl.addVersionFromExistent()">Add Version From Existent</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entaxy-cicd-header-buttons-container">
|
||||
<button type="button" ng-click="$ctrl.commit()">Commit</button>
|
||||
<button type="button" ng-click="$ctrl.build()">Build</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="entaxy-cicd-content-container">
|
||||
<entaxy-ci-cd-objects storage="$ctrl.storage" project="$ctrl.project" version="$ctrl.version"
|
||||
ng-if="$ctrl.version"></entaxy-ci-cd-objects>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyCICDProjectController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCICDProjectController(workspace, entaxyCICDService, $uibModal) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
ctrl.project = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
ctrl.isVersionSelected = EntaxyCICD.isVersion(workspace.selection);
|
||||
|
||||
if (ctrl.isVersionSelected) {
|
||||
ctrl.version = workspace.selection.title;
|
||||
} else {
|
||||
populateVersions();
|
||||
}
|
||||
}
|
||||
|
||||
function populateVersions() {
|
||||
ctrl.versions = EntaxyCICD.getVersions(workspace.selection);
|
||||
if (ctrl.versions.length > 0) {
|
||||
ctrl.version = ctrl.versions[ctrl.versions.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
function getFormFields() {
|
||||
return [
|
||||
{
|
||||
label: 'Current Version',
|
||||
name: 'currentVersion',
|
||||
type: 'text',
|
||||
value: ctrl.version,
|
||||
readOnly: true
|
||||
},
|
||||
{
|
||||
label: 'Created Version',
|
||||
name: 'createdVersion',
|
||||
type: 'text',
|
||||
required: true,
|
||||
validation: {
|
||||
checkUniqueness: true,
|
||||
values: ctrl.versions,
|
||||
content: {
|
||||
regex: '^([1-9][0-9]*|0)\\.([1-9][0-9]*|0)\\.([1-9][0-9]*|0)$',
|
||||
errorMessage: 'Value must match the pattern: X.X.X, where X represents a number'
|
||||
}
|
||||
},
|
||||
setFocused: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
ctrl.addVersionFromScratch = function () {
|
||||
openCreateVersionModal(getFormFields());
|
||||
}
|
||||
|
||||
ctrl.addVersionFromExistent = function () {
|
||||
let formFields = getFormFields();
|
||||
formFields.push({
|
||||
label: 'Prototype Version',
|
||||
name: 'prototypeVersion',
|
||||
enum: true,
|
||||
required: true,
|
||||
values: ctrl.versions,
|
||||
value: ctrl.version
|
||||
});
|
||||
openCreateVersionModal(formFields);
|
||||
}
|
||||
|
||||
function openCreateVersionModal(formFields) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Create Version',
|
||||
formFields: () => formFields
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
args.shift();
|
||||
createVersion(...args);
|
||||
}, reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createVersion(createdVersion, prototypeVersion) {
|
||||
entaxyCICDService.executeOperation('createVersion',
|
||||
[ctrl.storage, ctrl.project, createdVersion, prototypeVersion])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
entaxyCICDService.treeUpdated();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
ctrl.commit = function () {
|
||||
processOperation('saveProjectVersion');
|
||||
}
|
||||
|
||||
ctrl.build = function () {
|
||||
processOperation('buildProjectVersion');
|
||||
}
|
||||
|
||||
function processOperation(operationName) {
|
||||
entaxyCICDService.executeOperation(operationName, [ctrl.storage, ctrl.project, ctrl.version])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
|
||||
if (operationName === 'buildProjectVersion') {
|
||||
workspace.jmxTreeUpdated();
|
||||
}
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
entaxyCICDProjectController.$inject = ['workspace', 'entaxyCICDService', '$uibModal'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,146 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdProjects', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-content-with-title-container">
|
||||
<h2>
|
||||
Projects
|
||||
</h2>
|
||||
|
||||
<entaxy-ci-cd-applications-table type="Project" create-project="$ctrl.showCreateProjectModal">
|
||||
</entaxy-ci-cd-applications-table>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDProjectsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDProjectsController(workspace, $uibModal, entaxyCICDService, $scope, $route) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
const isStorageSelected = EntaxyCICD.isStorage(workspace.selection);
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
}
|
||||
|
||||
ctrl.showCreateProjectModal = function(items) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Create Project',
|
||||
formFields: () => getFormFields(items)
|
||||
},
|
||||
backdrop: 'static'
|
||||
})
|
||||
.result.then(args => {
|
||||
createProject(args);
|
||||
},
|
||||
reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getFormFields(items) {
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
type: 'text',
|
||||
required: true,
|
||||
validation: {
|
||||
checkUniqueness: true,
|
||||
values: items.map(project => project.name),
|
||||
content: {
|
||||
regex: '^[a-zA-Z0-9-_]+$',
|
||||
errorMessage: 'Value must contain only latin letters, numbers, hyphens and underscores'
|
||||
},
|
||||
length: {
|
||||
min: 3
|
||||
}
|
||||
},
|
||||
setFocused: true
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
label: 'Group',
|
||||
type: 'text',
|
||||
validation: {
|
||||
content: {
|
||||
regex: '^[a-zA-Z0-9-_]*$',
|
||||
errorMessage: 'Value must contain only latin letters, numbers, hyphens and underscores'
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'storage',
|
||||
label: 'Storage',
|
||||
type: 'string',
|
||||
value: isStorageSelected ? workspace.selection.title : undefined,
|
||||
enum: isStorageSelected ? undefined : true,
|
||||
values: isStorageSelected ? undefined : workspace.selection.children.map(child => child.title),
|
||||
required: true,
|
||||
readOnly: isStorageSelected ? true : undefined
|
||||
},
|
||||
{
|
||||
name: 'version',
|
||||
label: 'Version',
|
||||
type: 'string',
|
||||
value: '1.0.0',
|
||||
required: true,
|
||||
validation: {
|
||||
content: {
|
||||
regex: '^([1-9][0-9]*|0)\.([1-9][0-9]*|0)\.([1-9][0-9]*|0)$',
|
||||
errorMessage: 'Value must match the pattern: X.X.X, where X represents the number'
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function createProject(args) {
|
||||
let projectName = args[1] ? args[1] + '/' + args[0] : args[0];
|
||||
entaxyCICDService.executeOperation('createProject', [projectName, args[2], args[3]])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
entaxyCICDService.treeUpdated();
|
||||
})
|
||||
.catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDProjectsController.$inject = ['workspace', '$uibModal', 'entaxyCICDService', '$scope', '$route'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,246 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdProjectVersions', {
|
||||
template:
|
||||
`
|
||||
<div class="entaxy-cicd-content-with-title-container">
|
||||
<h2>{{$ctrl.title}}</h2>
|
||||
|
||||
<pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig">
|
||||
<actions>
|
||||
<span class="dropdown primary-action" uib-dropdown>
|
||||
<button class="dropdown-toggle" uib-dropdown-toggle type="button">
|
||||
Add Version
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li role="menuitem" ng-click="$ctrl.addVersionFromScratch()">
|
||||
<a class="secondary-action">Add Version From Scratch</a>
|
||||
</li>
|
||||
<li role="menuitem" ng-click="$ctrl.addVersionFromExistent()">
|
||||
<a class="secondary-action">Add Version From Existent</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</actions>
|
||||
</pf-toolbar>
|
||||
<pf-table-view class="entaxy-cicd-table"
|
||||
config="$ctrl.tableConfig"
|
||||
columns="$ctrl.tableColumns"
|
||||
action-buttons="$ctrl.tableActionButtons"
|
||||
page-config="$ctrl.pageConfig"
|
||||
items="$ctrl.viewedItems">
|
||||
</pf-table-view>
|
||||
</div>
|
||||
`,
|
||||
controller: entaxyCICDProjectVersionsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCICDProjectVersionsController($scope, workspace, entaxyCICDService, $uibModal, $templateCache,
|
||||
$location) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'name',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'name',
|
||||
title: 'Name',
|
||||
placeholder: 'Filter by Name...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'isBuilt',
|
||||
title: 'Build Available',
|
||||
placeholder: 'Filter by Built Availability...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
}
|
||||
],
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
actionsConfig: {
|
||||
actionsInclude: true
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{
|
||||
header: 'Name',
|
||||
itemField: 'name',
|
||||
htmlTemplate: 'project/version/name.html',
|
||||
colActionFn: (name) => ctrl.changeLocation(name)
|
||||
},
|
||||
{ header: 'Build Available', itemField: 'isBuilt',
|
||||
templateFn: (value) => EntaxyCICD.getStatusTemplate(value) }
|
||||
];
|
||||
|
||||
$templateCache.put(
|
||||
'project/version/name.html',
|
||||
'<a href="" ng-click="$ctrl.handleColAction(key, value)">{{value}}</a>'
|
||||
);
|
||||
|
||||
ctrl.changeLocation = function (name) {
|
||||
let nid = $location.search().nid;
|
||||
$location.search('nid', nid + '-' + 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;
|
||||
} else if (filter.id === 'isBuilt') {
|
||||
match = filter.value === 'yes' ? item.isBuilt === true : item.isBuilt === false;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
ctrl.storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
ctrl.project = workspace.selection.title;
|
||||
|
||||
ctrl.title = 'Versions';
|
||||
|
||||
ctrl.tableActionButtons = [
|
||||
{ name: 'Remove', title: 'Remove Version', actionFn: removeVersion }
|
||||
];
|
||||
|
||||
populateTable();
|
||||
}
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
function populateTable() {
|
||||
let selectedProject = workspace.selection;
|
||||
if (selectedProject.children && selectedProject.children.length > 0) {
|
||||
let versions = [];
|
||||
selectedProject.children.forEach(version => {
|
||||
versions.push({
|
||||
name: version.title,
|
||||
isBuilt: version.children && version.children.length === 1 ? true : false
|
||||
});
|
||||
});
|
||||
|
||||
ctrl.items = versions;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
}
|
||||
}
|
||||
|
||||
function getFormFields() {
|
||||
return [
|
||||
{
|
||||
label: 'Created Version',
|
||||
name: 'createdVersion',
|
||||
type: 'text',
|
||||
required: true,
|
||||
validation: {
|
||||
checkUniqueness: true,
|
||||
values: ctrl.items.map(version => version.name),
|
||||
content: {
|
||||
regex: '^([1-9][0-9]*|0)\\.([1-9][0-9]*|0)\\.([1-9][0-9]*|0)$',
|
||||
errorMessage: 'Value must match the pattern: X.X.X, where X represents a number'
|
||||
}
|
||||
},
|
||||
setFocused: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
ctrl.addVersionFromScratch = function () {
|
||||
openCreateVersionModal(getFormFields());
|
||||
}
|
||||
|
||||
ctrl.addVersionFromExistent = function () {
|
||||
let formFields = getFormFields();
|
||||
formFields.push({
|
||||
label: 'Prototype Version',
|
||||
name: 'prototypeVersion',
|
||||
enum: true,
|
||||
required: true,
|
||||
values: ctrl.items.map(version => version.name)
|
||||
});
|
||||
openCreateVersionModal(formFields);
|
||||
}
|
||||
|
||||
function openCreateVersionModal(formFields) {
|
||||
$uibModal.open({
|
||||
component: 'entaxyCiCdSimpleFieldsModal',
|
||||
resolve: {
|
||||
modalTitle: () => 'Create Version',
|
||||
formFields: () => formFields
|
||||
},
|
||||
backdrop: 'static'
|
||||
}).result.then((args) => {
|
||||
createVersion(...args);
|
||||
}, reason => {
|
||||
if (reason && reason !== Entaxy.MODAL_CANCEL_REASON.ESCAPE_KEY_PRESS) {
|
||||
Entaxy.notificationError(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createVersion(createdVersion, prototypeVersion) {
|
||||
entaxyCICDService.executeOperation('createVersion',
|
||||
[ctrl.storage, ctrl.project, createdVersion, prototypeVersion])
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
entaxyCICDService.treeUpdated();
|
||||
}).catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
function removeVersion(action, item) {
|
||||
let properties = [ctrl.storage, ctrl.project, item.name];
|
||||
entaxyCICDService.removeItemWithConfirmation(EntaxyCICD.ITEM_TYPE.VERSION, item.name, properties);
|
||||
}
|
||||
}
|
||||
entaxyCICDProjectVersionsController.$inject = ['$scope', 'workspace', 'entaxyCICDService', '$uibModal',
|
||||
'$templateCache', '$location'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,153 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdRequirements', {
|
||||
bindings: {
|
||||
version: '<',
|
||||
type: '@'
|
||||
},
|
||||
template:
|
||||
`
|
||||
<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: EntaxyCICDRequirementsController
|
||||
})
|
||||
.name;
|
||||
|
||||
function EntaxyCICDRequirementsController(workspace, $scope, $uibModal, entaxyCICDService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.tableConfig = {
|
||||
selectionMatchProp: 'id',
|
||||
showCheckboxes: false
|
||||
};
|
||||
|
||||
ctrl.toolbarConfig = {
|
||||
filterConfig: {
|
||||
fields: [
|
||||
{
|
||||
id: 'id',
|
||||
title: 'Id',
|
||||
placeholder: 'Filter by Id...',
|
||||
filterType: 'text'
|
||||
},
|
||||
{
|
||||
id: 'type',
|
||||
title: 'Type',
|
||||
placeholder: 'Filter by Type...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'scope',
|
||||
title: 'Scope',
|
||||
placeholder: 'Filter by Scope...',
|
||||
filterType: 'select',
|
||||
filterValues: []
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
title: 'Status',
|
||||
placeholder: 'Filter by Status...',
|
||||
filterType: 'select',
|
||||
filterValues: ['yes', 'no']
|
||||
}
|
||||
],
|
||||
inlineResults: true,
|
||||
appliedFilters: [],
|
||||
onFilterChange: filterChange
|
||||
},
|
||||
isTableView: true
|
||||
};
|
||||
|
||||
ctrl.tableColumns = [
|
||||
{ header: 'Id', itemField: 'id' },
|
||||
{ header: 'Type', itemField: 'type' },
|
||||
{ header: 'Scope', itemField: 'scope' },
|
||||
{ header: 'Status', itemField: 'status', templateFn: (value) => EntaxyCICD.getStatusTemplate(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) {
|
||||
let match = true;
|
||||
if (filter.id === 'id') {
|
||||
match = item.id.toLowerCase().match(filter.value.toLowerCase()) !== null;
|
||||
} else if (filter.id === 'type') {
|
||||
match = item.type === filter.value;
|
||||
} else if (filter.id === 'scope') {
|
||||
match = item.scope === filter.value;
|
||||
} else if (filter.id === 'status') {
|
||||
match = filter.value === 'yes' ? item.status === true : item.status === false;
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
ctrl.items = [];
|
||||
ctrl.viewedItems = [];
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
entaxyCICDService.setTypesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
|
||||
entaxyCICDService.setScopesToFilterConfig(ctrl.toolbarConfig.filterConfig.fields);
|
||||
}
|
||||
|
||||
$scope.$watch('$ctrl.version', function () {
|
||||
populateTable();
|
||||
});
|
||||
|
||||
function populateTable() {
|
||||
|
||||
const storage = EntaxyCICD.getStorage(workspace.selection);
|
||||
const application = EntaxyCICD.getProjectOrApplication(workspace.selection);
|
||||
let operationName = 'list' + ctrl.type + 'Requirements';
|
||||
|
||||
entaxyCICDService.executeOperation(operationName, [storage, application, ctrl.version])
|
||||
.then(result => {
|
||||
let items = JSON.parse(result);
|
||||
ctrl.items = items;
|
||||
filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
|
||||
});
|
||||
}
|
||||
}
|
||||
EntaxyCICDRequirementsController.$inject = ['workspace', '$scope', '$uibModal', 'entaxyCICDService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,147 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdSimpleFieldsModal', {
|
||||
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.resource" set-focused="formField.setFocused">
|
||||
<entaxy-select-from-enum id="{{formField.name}}" values="formField.values"
|
||||
model="formField.value" readonly="formField.readOnly" is-empty-included="false"
|
||||
ng-if="formField.enum" set-focused="formField.setFocused"></entaxy-select-from-enum>
|
||||
<entaxy-resource-input id="{{formField.name}}" name="{{formField.name}}" model="formField.value"
|
||||
ng-if="formField.resource"></entaxy-resource-input>
|
||||
<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: entaxyCICDSimpleFieldsModalController
|
||||
})
|
||||
.name;
|
||||
|
||||
function entaxyCICDSimpleFieldsModalController($scope, $uibModal, entaxyService, entaxyHotkeysService) {
|
||||
'ngInject';
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
entaxyHotkeysService.setHotkeys($scope, getHotkeysConfigs());
|
||||
|
||||
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.required && (formField.value === undefined ||
|
||||
(!formField.resource && formField.value.trim().length === 0))) {
|
||||
errors[formField.name] = Entaxy.ERROR_MESSAGE.EMPTY;
|
||||
}
|
||||
|
||||
if (!errors[formField.name] && formField.validation) {
|
||||
let validation = { ...formField.validation };
|
||||
delete validation.checkUniqueness;
|
||||
delete validation.values;
|
||||
|
||||
entaxyService.validateByRules(formField, validation, errors);
|
||||
}
|
||||
|
||||
if (!errors[formField.name] && formField.validation && formField.validation.checkUniqueness
|
||||
&& formField.validation.values.includes(formField.value)) {
|
||||
errors[formField.name] = Entaxy.ERROR_MESSAGE.UNIQUE;
|
||||
}
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
function getHotkeysConfigs() {
|
||||
return [
|
||||
{
|
||||
...Entaxy.getSaveHotkeyDescription(),
|
||||
callback: function (event) {
|
||||
event.preventDefault();
|
||||
ctrl.save();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
entaxyCICDSimpleFieldsModalController.$inject = ['$scope', '$uibModal', 'entaxyService', 'entaxyHotkeysService'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,263 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.component('entaxyCiCdTreeHeader', {
|
||||
template:
|
||||
`
|
||||
<div class="tree-nav-sidebar-header">
|
||||
<form role="form" class="search-pf has-button">
|
||||
<div class="form-group has-clear">
|
||||
<div class="search-pf-input-group">
|
||||
<label for="input-search" class="sr-only">Search Tree:</label>
|
||||
<input id="input-search" type="search" class="form-control" placeholder="Search tree:"
|
||||
ng-model="$ctrl.filter">
|
||||
<button type="button" class="clear" aria-hidden="true"
|
||||
ng-hide="$ctrl.filter.length === 0"
|
||||
ng-click="$ctrl.filter = ''">
|
||||
<span class="pficon pficon-close"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group tree-nav-buttons">
|
||||
<span class="badge" ng-class="{positive: $ctrl.result.length > 0}"
|
||||
ng-show="$ctrl.filter.length > 0">
|
||||
{{$ctrl.result.length}}
|
||||
</span>
|
||||
<i class="fa fa-plus-square-o" title="Expand All" ng-click="$ctrl.expandAll()"></i>
|
||||
<i class="fa fa-minus-square-o" title="Collapse All" ng-click="$ctrl.contractAll()"></i>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDTreeHeaderController
|
||||
}).component('entaxyCiCdTree', {
|
||||
template:
|
||||
`
|
||||
<div class="tree-nav-sidebar-content">
|
||||
<div id="entaxycicdtree" class="treeview-pf-hover treeview-pf-select"></div>
|
||||
</div>
|
||||
`,
|
||||
controller: EntaxyCICDTreeController
|
||||
})
|
||||
.name;
|
||||
entaxyCICDTreeElementId = '#entaxycicdtree';
|
||||
EntaxyCICD.log.debug("loaded tree" + EntaxyCICD.treeModule);
|
||||
|
||||
function EntaxyCICDTreeHeaderController($scope, $element) {
|
||||
'ngInject';
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController ");
|
||||
this.$scope = $scope;
|
||||
this.$element = $element;
|
||||
this.filter = '';
|
||||
this.result = [];
|
||||
// it's not possible to declare classes to the component host tag in AngularJS
|
||||
$element.addClass('tree-nav-sidebar-header');
|
||||
|
||||
EntaxyCICDTreeHeaderController.prototype.$onInit = function () {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController init");
|
||||
var _this = this;
|
||||
this.$scope.$watch(angular.bind(this, function () { return _this.filter; }), function (filter, previous) {
|
||||
if (filter !== previous) {
|
||||
_this.search(filter);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
EntaxyCICDTreeHeaderController.prototype.search = function (filter) {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController search");
|
||||
var _this = this;
|
||||
var doSearch = function (filter) {
|
||||
var result = _this.tree().search(filter, {
|
||||
ignoreCase: true,
|
||||
exactMatch: false,
|
||||
revealResults: true
|
||||
});
|
||||
_this.result.length = 0;
|
||||
(_a = _this.result).push.apply(_a, result);
|
||||
Core.$apply(_this.$scope);
|
||||
var _a;
|
||||
};
|
||||
_.debounce(doSearch, 300, { leading: false, trailing: true })(filter);
|
||||
};
|
||||
|
||||
EntaxyCICDTreeHeaderController.prototype.tree = function () {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController tree");
|
||||
return $(entaxyCICDTreeElementId).treeview(true);
|
||||
};
|
||||
|
||||
EntaxyCICDTreeHeaderController.prototype.expandAll = function () {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController expand");
|
||||
return this.tree()
|
||||
.expandNode(this.tree().getNodes(), { levels: HawtioTree.getMaxTreeLevel(this.tree()), silent: true });
|
||||
};
|
||||
|
||||
EntaxyCICDTreeHeaderController.prototype.contractAll = function () {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeHeaderController contract");
|
||||
return this.tree()
|
||||
.collapseNode(this.tree().getNodes(), { ignoreChildren: true, silent: true });
|
||||
};
|
||||
}
|
||||
EntaxyCICDTreeHeaderController.$inject = ['$scope', '$element'];
|
||||
|
||||
function EntaxyCICDTreeController($scope, $location, workspace, $element, operationsService, $q) {
|
||||
'ngInject';
|
||||
this.$scope = $scope;
|
||||
this.$location = $location;
|
||||
this.workspace = workspace;
|
||||
this.$element = $element;
|
||||
// it's not possible to declare classes to the component host tag in AngularJS
|
||||
$element.addClass('tree-nav-sidebar-content');
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeController ");
|
||||
var entaxyCICDJmxDomain = localStorage['entaxyCICDJmxDomain'] || "ru.entaxy.cicd";
|
||||
|
||||
EntaxyCICDTreeController.prototype.$onInit = function () {
|
||||
EntaxyCICD.log.debug("EntaxyCICDTreeController onInit");
|
||||
var _this = this;
|
||||
this.$scope.$on('$destroy', function () { return _this.removeTree(); });
|
||||
this.$scope.$on('$routeChangeStart', function () {
|
||||
return Jmx.updateTreeSelectionFromURL(_this.$location, $(entaxyCICDTreeElementId));
|
||||
});
|
||||
this.$scope.$on('jmxTreeUpdated', function (event, opts) {
|
||||
let updateSelectionNode = opts ? opts.updateSelectionNode : false;
|
||||
return _this.populateTree(updateSelectionNode);
|
||||
});
|
||||
this.populateTree();
|
||||
};
|
||||
EntaxyCICDTreeController.prototype.updateSelectionFromURL = function () {
|
||||
Jmx.updateTreeSelectionFromURLAndAutoSelect(this.$location, $(entaxyCICDTreeElementId), null, true);
|
||||
};
|
||||
EntaxyCICDTreeController.prototype.populateTree = function (updateSelectionNode) {
|
||||
|
||||
let tree = this.workspace.tree;
|
||||
|
||||
if (tree) {
|
||||
let domain = tree.get(entaxyCICDJmxDomain);
|
||||
|
||||
if (domain && domain.children && domain.children.length > 0) {
|
||||
let promises = [];
|
||||
domain.children.forEach(child => {
|
||||
child.class = createClassName(child.title);
|
||||
promises.push(
|
||||
operationsService.executeOperation(child.objectName, {name: 'readAsTree'}, [])
|
||||
.then(result => {
|
||||
let nodes = JSON.parse(result);
|
||||
|
||||
let folderNames = child.key.split('-');
|
||||
folderNames.shift();
|
||||
let cicdTree = createTree(nodes, child.key, folderNames);
|
||||
cicdTree.forEach(cicdChild => {
|
||||
cicdChild.parent = child;
|
||||
});
|
||||
child.children = cicdTree;
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
$q.all(promises).then(() => {
|
||||
this.removeTree();
|
||||
Jmx.enableTree(this.$scope, this.$location, this.workspace,
|
||||
$(entaxyCICDTreeElementId), domain.children);
|
||||
this.updateSelectionFromURL();
|
||||
if (updateSelectionNode) {
|
||||
workspace.updateSelectionNode(workspace.selection);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
function createTree(children, keyPrefix, folderNames) {
|
||||
let folders = [];
|
||||
if (children && children.length > 0) {
|
||||
children.forEach(child => {
|
||||
let folder = new Jmx.Folder(child.title);
|
||||
let index = child.title.indexOf('[');
|
||||
if (index > 0) {
|
||||
folder.key = keyPrefix + '-' + child.title.slice(0, index - 1).toLowerCase();
|
||||
} else {
|
||||
folder.key = keyPrefix + '-' + child.title.toLowerCase();
|
||||
}
|
||||
let folderNamesCopy = folderNames.map(folderName => folderName);
|
||||
folderNamesCopy.push(index > 0 ? child.title.slice(0, index - 1) : child.title);
|
||||
folder.folderNames = folderNamesCopy;
|
||||
addClass(folder);
|
||||
folder.tooltip = folder.title;
|
||||
folder.domain = entaxyCICDJmxDomain;
|
||||
folder.children = createTree(child.children, folder.key, folderNamesCopy);
|
||||
if (folder.children && folder.children.length > 0) {
|
||||
folder.children.forEach(child => {
|
||||
child.parent = folder;
|
||||
})
|
||||
}
|
||||
folder.sortChildren();
|
||||
folders.push(folder);
|
||||
});
|
||||
}
|
||||
return folders;
|
||||
}
|
||||
function addClass(folder) {
|
||||
switch (folder.folderNames.length) {
|
||||
case 3:
|
||||
folder.class = createClassName('storages');
|
||||
break;
|
||||
case 4:
|
||||
folder.class = createClassName(folder.folderNames[1]);
|
||||
break;
|
||||
case 5:
|
||||
folder.class = createClassName('versions');
|
||||
break;
|
||||
case 6:
|
||||
folder.class = createClassName(folder.folderNames[1] === 'applications' ?
|
||||
'revisions' : 'build-info');
|
||||
break;
|
||||
}
|
||||
}
|
||||
function createClassName(folderName) {
|
||||
return 'entaxy-cicd-' + folderName + '-icon';
|
||||
}
|
||||
EntaxyCICDTreeController.prototype.removeTree = function () {
|
||||
var tree = $(entaxyCICDTreeElementId).treeview(true);
|
||||
// There is no exposed API to check whether the tree has already been initialized,
|
||||
// so let's just check if the methods are present
|
||||
if (tree.clearSearch) {
|
||||
tree.clearSearch();
|
||||
// Bootstrap tree view leaks the node elements into the data structure
|
||||
// so let's clean this up when the user leaves the view
|
||||
var cleanTreeFolder_1 = function (node) {
|
||||
delete node['$el'];
|
||||
if (node.nodes)
|
||||
node.nodes.forEach(cleanTreeFolder_1);
|
||||
};
|
||||
cleanTreeFolder_1(this.workspace.tree);
|
||||
// Then call the tree clean-up method
|
||||
tree.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICDTreeController.$inject = ['$scope', '$location', 'workspace', '$element', 'operationsService', '$q'];
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,155 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
|
||||
const REVISION_STATUS = {
|
||||
CONFIGURED: 'CONFIGURED',
|
||||
DEPLOYED: 'DEPLOYED',
|
||||
INSTALLED: 'INSTALLED',
|
||||
UNINSTALLED: 'UNINSTALLED'
|
||||
}
|
||||
EntaxyCICD.REVISION_STATUS = REVISION_STATUS;
|
||||
|
||||
const ITEM_TYPE = {
|
||||
APPLICATION: 'Application',
|
||||
PROJECT: 'Project',
|
||||
VERSION: 'Version'
|
||||
}
|
||||
EntaxyCICD.ITEM_TYPE = ITEM_TYPE;
|
||||
|
||||
function isStorage(selection) {
|
||||
return selection.folderNames && selection.folderNames.length === 3;
|
||||
}
|
||||
EntaxyCICD.isStorage = isStorage;
|
||||
|
||||
function getStorage(selection) {
|
||||
if (selection.folderNames) {
|
||||
switch (selection.folderNames.length) {
|
||||
case 3:
|
||||
return selection.title;
|
||||
case 4:
|
||||
return selection.parent.title;
|
||||
case 5:
|
||||
return selection.parent.parent.title;
|
||||
case 6:
|
||||
return selection.parent.parent.parent.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICD.getStorage = getStorage;
|
||||
|
||||
function getStorages(selection) {
|
||||
return selection.children && selection.children.length > 0 ? selection.children.map(child => child.title) : [];
|
||||
}
|
||||
EntaxyCICD.getStorages = getStorages;
|
||||
|
||||
function getProjectOrApplication(selection) {
|
||||
if (selection.folderNames) {
|
||||
switch (selection.folderNames.length) {
|
||||
case 4:
|
||||
return selection.title;
|
||||
case 5:
|
||||
return selection.parent.title;
|
||||
case 6:
|
||||
return selection.parent.parent.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICD.getProjectOrApplication = getProjectOrApplication;
|
||||
|
||||
function isVersion(selection) {
|
||||
return selection.folderNames && selection.folderNames.length === 5;
|
||||
}
|
||||
EntaxyCICD.isVersion = isVersion;
|
||||
|
||||
function getVersion(selection) {
|
||||
if (selection.folderNames) {
|
||||
switch (selection.folderNames.length) {
|
||||
case 5:
|
||||
return selection.title;
|
||||
case 6:
|
||||
return selection.parent.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyCICD.getVersion = getVersion;
|
||||
|
||||
function getVersions(selection) {
|
||||
return selection.children && selection.children.length > 0 ? selection.children.map(child => child.title) : [];
|
||||
}
|
||||
EntaxyCICD.getVersions = getVersions;
|
||||
|
||||
function isRevision(selection) {
|
||||
return selection.folderNames && selection.folderNames.length === 6;
|
||||
}
|
||||
EntaxyCICD.isRevision = isRevision;
|
||||
|
||||
function getRevisionInfo(selection) {
|
||||
let splitTitle = selection.title.split(' ');
|
||||
return {
|
||||
revision: splitTitle[0],
|
||||
revisionStatus: splitTitle[1].replace(/\[|]/g, '')
|
||||
};
|
||||
}
|
||||
EntaxyCICD.getRevisionInfo = getRevisionInfo;
|
||||
|
||||
function getStatusTemplate(value) {
|
||||
if (value) {
|
||||
return '<span class="pficon pficon-ok"></span>'
|
||||
} else {
|
||||
return '<span class="pficon pficon-error-circle-o blue"></span>';
|
||||
}
|
||||
}
|
||||
EntaxyCICD.getStatusTemplate = getStatusTemplate;
|
||||
|
||||
function capitalize(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
EntaxyCICD.capitalize = capitalize;
|
||||
|
||||
function createTableFromUnremovedItems(unremovedItemsInfo) {
|
||||
let tableHtml = `<table class="entaxy-cicd-unremoved-info-table">`;
|
||||
tableHtml += `
|
||||
<tr>
|
||||
<th>Item</th>
|
||||
<th>Required By</th>
|
||||
</tr>
|
||||
`;
|
||||
Object.entries(unremovedItemsInfo).forEach(([itemId, listRequiredBy]) => {
|
||||
tableHtml += `<tr><td>` + itemId + `</td><td>`;
|
||||
listRequiredBy.forEach(requiredBy => {
|
||||
tableHtml += requiredBy + '\n';
|
||||
});
|
||||
tableHtml += `</td></tr>`;
|
||||
});
|
||||
tableHtml += `</table>`;
|
||||
return tableHtml;
|
||||
}
|
||||
EntaxyCICD.createTableFromUnremovedItems = createTableFromUnremovedItems;
|
||||
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
@ -0,0 +1,93 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-management-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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~~~~~~
|
||||
*/
|
||||
/**
|
||||
* The main entry point for the Simple module
|
||||
*/
|
||||
var EntaxyCICD = (function (EntaxyCICD) {
|
||||
|
||||
/**
|
||||
* The name of this plugin
|
||||
*/
|
||||
EntaxyCICD.pluginName = 'entaxy-cicd';
|
||||
|
||||
/**
|
||||
* This plugin's logger instance
|
||||
*/
|
||||
EntaxyCICD.log = Logger.get('entaxy-cicd');
|
||||
|
||||
/**
|
||||
* The top level path of this plugin on the server
|
||||
*/
|
||||
EntaxyCICD.contextPath = "/entaxy-cicd/";
|
||||
|
||||
EntaxyCICD.log.info("loading entaxy cicd plugin")
|
||||
EntaxyCICD._module = angular.module(EntaxyCICD.pluginName, [
|
||||
'angularResizable'
|
||||
])
|
||||
.component('entaxyCiCd', {
|
||||
template:
|
||||
`
|
||||
<div class="tree-nav-layout">
|
||||
<div class="sidebar-pf sidebar-pf-left" resizable r-directions="['right']">
|
||||
<entaxy-ci-cd-tree-header></entaxy-ci-cd-tree-header>
|
||||
<entaxy-ci-cd-tree></entaxy-ci-cd-tree>
|
||||
</div>
|
||||
<div class="tree-nav-main">
|
||||
<entaxy-ci-cd-navigation></entaxy-ci-cd-navigation>
|
||||
<entaxy-ci-cd-contents></entaxy-ci-cd-contents>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
.run(configurePlugin);
|
||||
|
||||
function configurePlugin(mainNavService, workspace, helpRegistry, preferencesRegistry, localStorage) {
|
||||
|
||||
var entaxyCICDJmxDomain = localStorage['entaxyCICDJmxDomain'] || "ru.entaxy.cicd";
|
||||
mainNavService.addItem({
|
||||
title: 'Entaxy CI/CD',
|
||||
basePath: '/entaxy-cicd',
|
||||
template: '<entaxy-ci-cd></entaxy-ci-cd>',
|
||||
isValid: function () { return workspace.treeContainsDomainAndProperties(entaxyCICDJmxDomain); },
|
||||
rank: 2
|
||||
});
|
||||
|
||||
// clean up local storage upon logout
|
||||
/* preLogoutTasks.addTask('CleanupArtemisCredentials', function () {
|
||||
Artemis.log.debug("Clean up Artemis credentials in local storage");
|
||||
localStorage.removeItem('artemisUserName');
|
||||
localStorage.removeItem('artemisPassword');
|
||||
}); */
|
||||
}
|
||||
configurePlugin.$inject = ['mainNavService', 'workspace', 'helpRegistry', 'preferencesRegistry', 'localStorage'];
|
||||
|
||||
return EntaxyCICD;
|
||||
|
||||
})(EntaxyCICD || {});
|
||||
|
||||
// tell the Hawtio plugin loader about our plugin so it can be
|
||||
// bootstrapped with the rest of AngularJS
|
||||
hawtioPluginLoader.addModule(EntaxyCICD.pluginName);
|
@ -0,0 +1,125 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* entaxy-cicd-plugin
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2025 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 EntaxyCICD;
|
||||
(function (EntaxyCICD) {
|
||||
EntaxyCICD._module.factory('entaxyCICDService', ['$q', 'workspace', 'jolokia', 'jolokiaService', 'operationsService',
|
||||
'$uibModal', 'entaxyService',
|
||||
function($q, workspace, jolokia, jolokiaService, operationsService, $uibModal, entaxyService) {
|
||||
|
||||
const entaxyCICDJmxDomain = localStorage['entaxyCICDJmxDomain'] || "ru.entaxy.cicd";
|
||||
|
||||
return {
|
||||
executeOperation: function (operationName, properties) {
|
||||
return executeOperation(operationName, properties);
|
||||
},
|
||||
treeUpdated: function () {
|
||||
return treeUpdated();
|
||||
},
|
||||
setTypesToFilterConfig: function (filterFields) {
|
||||
return setValuesToFilterConfig(filterFields, 'type', 'readApplicationItemTypes');
|
||||
},
|
||||
setScopesToFilterConfig: function (filterFields) {
|
||||
return setValuesToFilterConfig(filterFields, 'scope', 'readApplicationItemScopes');
|
||||
},
|
||||
removeItemWithConfirmation: function (itemType, itemName, properties, updateSelectionNode, message) {
|
||||
return removeItemWithConfirmation(itemType, itemName, properties, updateSelectionNode, message);
|
||||
}
|
||||
};
|
||||
|
||||
function executeOperation(operationName, properties) {
|
||||
let mbeanName = getCICDMBeanName();
|
||||
let operation = { name : operationName };
|
||||
|
||||
if (mbeanName) {
|
||||
return operationsService.executeOperation(mbeanName, operation, properties);
|
||||
} else {
|
||||
return $q.reject("Cannot find mbean for CI/CD");
|
||||
}
|
||||
}
|
||||
|
||||
function treeUpdated () {
|
||||
let rootScope = workspace.$rootScope;
|
||||
if (rootScope) {
|
||||
Core.$apply(rootScope);
|
||||
rootScope.$broadcast(Jmx.TreeEvent.Updated, { updateSelectionNode: true });
|
||||
}
|
||||
}
|
||||
|
||||
function setValuesToFilterConfig(filterFields, fieldId, operationName) {
|
||||
let mbean = workspace.findMBeanWithProperties(entaxyCICDJmxDomain, { module: 'applications' });
|
||||
let operation = { name: operationName };
|
||||
|
||||
operationsService.executeOperation(mbean.objectName, operation, [])
|
||||
.then(result => {
|
||||
let toolbarConfigTypeField = filterFields.find(field => field.id === fieldId);
|
||||
toolbarConfigTypeField.filterValues = JSON.parse(result);
|
||||
});
|
||||
}
|
||||
|
||||
function removeItemWithConfirmation(itemType, itemName, properties, updateSelectionNode, message) {
|
||||
let title = 'Confirm Removing';
|
||||
if (!message) {
|
||||
message = 'Do you want to remove the ' + itemType.toLowerCase() + ' ' + itemName + '?';
|
||||
}
|
||||
|
||||
entaxyService.openConfirmationWindow(title, message).then(() => {
|
||||
executeOperation('remove' + itemType, properties)
|
||||
.then(result => {
|
||||
Entaxy.notificationSuccess(result);
|
||||
if (updateSelectionNode) {
|
||||
treeUpdated();
|
||||
} else {
|
||||
workspace.jmxTreeUpdated();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Entaxy.notificationError(error);
|
||||
EntaxyCICD.log.error(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getCICDMBeanName() {
|
||||
if (!workspace.hasDomainAndProperties(entaxyCICDJmxDomain)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tree = workspace.tree;
|
||||
if (tree) {
|
||||
let domain = tree.get(entaxyCICDJmxDomain);
|
||||
if (domain && domain.children) {
|
||||
for (let i = 0; i < domain.children.length; i++) {
|
||||
if (domain.children[i].folderNames[1] === workspace.selection.folderNames[1]) {
|
||||
return domain.children[i].objectName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
})(EntaxyCICD || (EntaxyCICD = {}));
|
Reference in New Issue
Block a user