Initial commit

This commit is contained in:
Isaac Parenteau committed 2018-07-07 20:43:51 -05:00
commit 880e39de2e
511 files changed
+38363

No files matched your search

+523
View File
@@ -0,0 +1,523 @@
/*csslint important: false*/
#mainBody {
background-color: #ff6600;
background: url(images/background.png);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.fill-height {
height: 100% !important;
}
.header-container-left,
.header-container,
.header-container-right {
display: inline-block;
vertical-align: middle;
margin: 0 5px;
height: 40px;
}
.header-container-left {
left: 0;
}
.header-container-right {
position: absolute;
right: 0;
}
.vertical-align-center,
.header-container-right button {
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-o-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
position: relative;
top: 50%;
}
.horizontal-align-center {
position: relative;
left: 50%;
-moz-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
}
.center-text {
text-align: center;
}
#filterBoxAlignment{
bottom: -2px;
left:1.5px;
background-color: #FFFFFF;
}
#bottomFilter{
height: 35px;
bottom: 3px;
left: 1px;
background-color: #EBEBEB;
}
#box{
bottom:50px;
}
.left-text {
text-align: left;
}
html,
body {
margin: 0;
padding: 0;
border: 0;
}
body {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden !important;
}
.fill-height-scroll,
.fill-height-scroll .tab-pane {
height: 100%;
overflow:auto;
}
.fill-height-scroll-y,
.fill-height-scroll-y .tab-pane {
height: 100%;
overflow-y:auto;
overflow-x:no-content;
}
.scroll {
overflow: auto;
}
.box {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
.tab-pane {
padding: 5px;
}
.ellipsis {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.margin-none {
margin: 0;
}
.margin-sm {
margin: 3px;
}
.margin-md {
margin: 5px;
}
.margin-sides-xs {
margin-left: 2px;
margin-right: 2px;
}
.margin-sides-sm {
margin-left: 4px;
margin-right: 4px;
}
.margin-right-xs {
margin-right: 1px;
}
.margin-right-sm {
margin-right: 3px;
}
.margin-right-md {
margin-right: 5px;
}
.margin-right-lg {
margin-right: 10px;
}
.col-padding-none,
.padding-none {
padding: 0 !important;
}
.padding-left-none {
padding-left: 0;
}
.padding-med {
padding: 3px;
}
.padding-sides-small {
padding-left: 1px;
padding-right: 1px
}
.padding-sides-med {
padding-left: 3px;
padding-right: 3px;
}
.rounded-border {
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 8px;
}
/*
* lifecycle and ex org table css rules
*/
#availableLC{
height: 194px;
width: 472px;
}
#availableOT{
height: 430px;
width: 472px;
}
.thin-border {
border: 1px solid #ddd;
}
.thin-border-top {
border-top: 1px solid #ddd;
}
.thin-border-bottom {
border-bottom: 1px solid #ddd;
}
.thin-border-left {
border-left: 1px solid #ddd;
}
.thin-border-right {
border-right: 1px solid #ddd;
}
.thin-border-sides {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.progress-bar-label {
color: #555;
left:50%;
top:50%;
-o-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
position:absolute;
}
/*Allows label to be centered in progress bar using absolute positioning*/
.progress {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: relative;
}
.progress-bar {
box-shadow: none;
}
.tab-pane {
padding: 0;
}
.icon-xs svg {
float: left;/*Causes vertical centering to work with svg element*/
width: 16px;
height: 16px;
}
.text-small {
font-size: 10px;
}
.bold {
font-weight: bold;
}
/* This controls the border around the buttons when they have a selection focus
button :focus {
outline: none!important;
}*/
.gridStyle {
box-sizing: border-box;
border: 1px solid rgb(212,212,212);
}
.float-left {
float: left;
}
.float-right {
float: right;
}
.nav-tabs li:first-of-type {
padding-left: 4px; /** TODO Replace this with responsive utility*/
}
/* Override the default gray because it is hard to see. */
/* TODO: possible change to a different color/shade */
.modal-footer {
border-top-color: black;
}
.modal-header {
border-bottom-color: black;
}
.rotate90 {
/* Safari */
-webkit-transform: rotate(90deg);
/* Firefox */
-moz-transform: rotate(90deg);
/* IE */
-ms-transform: rotate(90deg);
/* Opera */
-o-transform: rotate(90deg);
transform: rotate(90deg);
/* One of these catches chrome */
}
.rotate180 {
/* Safari */
-webkit-transform: rotate(180deg);
/* Firefox */
-moz-transform: rotate(180deg);
/* IE */
-ms-transform: rotate(180deg);
/* Opera */
-o-transform: rotate(180deg);
transform: rotate(180deg);
/* One of these catches chrome */
}
/* Prevents drag and shift text selection */
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor:default;
}
/*
.modal.fade .modal-dialog, .modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}*/
#modalDialogContainer>div{
overflow-y: hidden;
overflow-x: hidden;
}
.modal-body {
overflow: hidden;
padding-top: 5;
padding-bottom: 0;
}
.input-group-addon:not(:last-child),
.input-group-btn:not(:last-child),
.input-group .form-control:not(:last-child) {
border-right: none;
}
.input-group-btn:last-child>.btn,
.input-group-btn:last-child>.btn-group {
margin-left: 0;
}
.no-scroll-table .ngViewport {
height: auto !important;
}
.no-scroll-table .ngCanvas,
.no-scroll-table .ngViewport,
.no-scroll-table .ngRow,
.no-scroll-table .ngFooterPanel,
.no-scroll-table .ngTopPanel{
width: 100% !important;
}
.no-scroll-table .ngRow {
border-bottom: none !important;
border-radius: 5px !important;
}
.panel-body-relative {
position: relative;
}
.normal-filter {
background-color: white;
height: 40px;
width: 200px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
padding-bottom: 40px;
}
.bottom-filter {
background-color: white;
height: 40px;
position: absolute;
bottom: 0;
width: 200px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
}
.bottom-filter-pad {
padding-bottom: 40px; /** Cooresponds with .bottom-filter */
}
/* Causes an element to fill it's absolute container fully */
.fill-container-absolutely {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/** Fixes issue with loading spinner showing up in front of modal dialogues */
.spinner {
z-index: 0 !important;
}
/**
* Hides the pin button unless you hover over the header for ng-grid
*/
.ngUnPinnedIcon {
visibility: hidden;
}
.ngHeaderCell:hover .ngUnPinnedIcon {
visibility: visible;
}
.glyphicon-tile.glyphicon {
text-align: center;
font-size: 8em;
color: lightgray;
}
.label-as-badge {
border-radius: 1em;
}
.loadingFade {
position:absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ababab;
z-index: 9000;
-moz-opacity: 0.8;
opacity: .70;
filter: alpha(opacity=80);
}
.loadingModal {
position: absolute;
top: 45%;
left: 48%;
z-index: 9001;
text-align:center;
}
.splitter{
background: #c8c8c8;
width: 1px;
}
.ghost {
background: #c8c8c8;
opacity: 0.5;
}
.ui-icon-gripsmall-diagonal-se {
right:0 !important;
bottom:0 !important;
background-position: -64px -224px !important;
}
.hover-cursor {
cursor: pointer;
cursor: hand;
}
.icon-grid-cell {
padding-top: 3px;
padding-left: 3px;
}
@media (min-width: 992px) {
.modal-xl {
width: 95%;
}
}
.ui-grid-sort-priority-number {
font-size: 0;
}
.stretch input {
width: 100%
}
.speech {
bottom: 0;
right: 0;
position: absolute;
}
+130
View File
@@ -0,0 +1,130 @@
var portal = angular.module('portal', [
'ui.bootstrap',
'ui.router',
'ui.grid',
'ui.grid.saveState',
'ui.grid.selection',
'ui.grid.edit',
'ui.grid.resizeColumns',
'ui.grid.moveColumns',
'ui.grid.expandable',
'ui.grid.pinning',
'ui.grid.autoResize',
'ui.grid.exporter',
'ui.grid.cellNav',
'ui.grid.pagination',
'ui.grid.treeView',
'ui.tinymce',
'ngResource',
'ngCookies',
'ngSanitize',
'ngAnimate',
'ngMessages',
'ngMaterial',
'ngMaterialDatePicker',
'debounce',
'portal.login',
'portal.dashboard',
'portal.dashboard.gitBank',
'portal.dashboard.userBank',
'portal.dashboard.credBank',
'portal.dashboard.logBank',
'portal.dashboard.scriptBank',
'portal.dashboard.emailBank',
'portal.dashboard.envBank',
'portal.dashboard.permissionBank',
'portal.common.constants',
'portal.common.factories.pubsub',
'portal.common.services.map',
'portal.common.services.model.cache',
'portal.common.services.model.rest',
'portal.common.services.portalUtils',
'portal.common.services.authorize',
'portal.common.services.triggers',
'portal.common.directives.portalTabset',
'portal.common.directives.compareTo',
'portal.common.directives.portalWebsocket',
'portal.common.directives.permissions',
'portal.common.partials.sessionEnd',
'portal.common.partials.uploadpatchfile',
'portal.common.partials.addGit',
'portal.common.partials.addUser',
'portal.common.partials.addDirectory',
'portal.common.partials.addCreds',
'portal.common.partials.addScript',
'portal.common.partials.addEnvVars',
'portal.common.partials.configuration',
'portal.common.partials.fileinfo',
'portal.common.partials.filevalidate',
'portal.common.partials.addPermission',
'portal.common.partials.viewScriptStatus',
'portal.common.partials.loggerinfo',
'portal.common.partials.smtpinfo',
'portal.common.partials.addEmailTmpl',
'portal.common.partials.seedinfo'
]);
angular.module('portal').config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/dashboard');
/* Add New States Above, or else in the module, but not in both */
$urlRouterProvider.when('', 'dashboard');
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$stateProvider.state('main', {
url: '/main',
pageTitle: 'Main',
templateUrl: 'main/main.html',
resolve: {
authorize: ['authorize',
function (authorize) {
return authorize.validate({
authorities: {
account: ['USER', 'ADMIN']
},
redirect: 'dashboard'
});
}
],
}
}).state('login', {
url: '/login',
pageTitle: 'Login',
templateUrl: 'login/login.html'
}).state('prohibited', {
url: '/prohibited',
pageTitle: 'Access Denied',
templateUrl: 'prohibited/prohibited.html'
}).state('main.prohibited', {
url: '/prohibited',
pageTitle: 'Access Denied',
templateUrl: 'prohibited/prohibited.html'
});
}); //end angular.module.config
angular.module('portal').run(function($rootScope, $state, $animate, $window, $location, $transitions) {
$transitions.onSuccess({to: 'dashboard.**' }, function(trans){
$rootScope.$broadcast('$stateChangeSuccess', trans.router.globals.$current.name);
});
$rootScope.$on('$locationChangeSuccess', function(){
$rootScope.actualLocation = $location.path();
});
// Allows easy unregistering of listener callbacks
// See https://stackoverflow.com/a/14898930
$rootScope.$off = function (name, listener) {
var namedListeners = $rootScope.$$listeners[name];
if (namedListeners) {
// Loop through the array of named listeners and remove them from the array.
for (var i = 0; i < namedListeners.length; i++) {
if (namedListeners[i] === listener) {
return namedListeners.splice(i, 1);
}
}
}
};
});//end angular.module.run
@@ -0,0 +1,43 @@
angular.module('portal.common.constants',[])
.constant('Constants',{
Permissions: {
VIEW_SCRIPT_TAB : 'VIEW_SCRIPT_TAB',
VIEW_GIT_TAB : 'VIEW_GIT_TAB',
VIEW_USER_TAB : 'VIEW_USER_TAB',
VIEW_CREDS_TAB : 'VIEW_CREDS_TAB',
VIEW_LOG_TAB : 'VIEW_LOG_TAB',
VIEW_PERMISSION_TAB : 'VIEW_PERMISSION_TAB',
VIEW_EMAIL_TAB : 'VIEW_EMAIL_TAB',
VIEW_ENV_VARS_TAB : 'VIEW_ENV_VARS_TAB',
VIEW_CONFIG : 'VIEW_CONFIG',
CHANGE_CONFIG : 'CHANGE_CONFIG',
VIEW_SMTP_CONFIG : 'VIEW_SMTP_CONFIG',
EDIT_SMTP_CONFIG : 'EDIT_SMTP_CONFIG',
VIEW_HASH_TYPES : 'VIEW_HASH_TYPES',
CHANGE_HASH_TYPES : 'CHANGE_HASH_TYPES',
ADD_USERS : 'ADD_USERS',
DELETE_USERS : 'DELETE_USERS',
PURGE_LOGS : 'PURGE_LOGS',
ADD_PERMS : 'ADD_PERMS',
DELETE_PERMS : 'DELETE_PERMS',
ADD_CREDENTIALS : 'ADD_CREDENTIALS',
DELETE_CREDENTIALS : 'DELETE_CREDENTIALS',
ADD_GIT_REPO : 'ADD_GIT_REPO',
PULL_GIT_REPO : 'PULL_GIT_REPO',
DELETE_GIT_REPO : 'DELETE_GIT_REPO',
ADD_EMAIL : 'ADD_EMAIL',
DELETE_EMAIL : 'DELETE_EMAIL',
RUN_SCRIPT : 'RUN_SCRIPT',
ADD_SCRIPT : 'ADD_SCRIPT',
DELETE_SCRIPT : 'DELETE_SCRIPT',
VIEW_SCRIPT_SCHED_STATUS : 'VIEW_SCRIPT_SCHED_STATUS',
DELETE_SCRIPT_SCHED_STATUS : 'DELETE_SCRIPT_SCHED_STATUS',
ADD_ENV_VARS : 'ADD_ENV_VARS',
DELETE_ENV_VARS : 'DELETE_ENV_VARS',
VIEW_ENV_VARS : 'VIEW_ENV_VARS',
VIEW_LOG_LEVELS : 'VIEW_LOG_LEVELS',
CHANGE_LOG_LEVELS : 'CHANGE_LOG_LEVELS',
DELETE_FILE : 'DELETE_FILE',
UPDATE_SEED_VALUE : 'UPDATE_SEED_VALUE'
}
});
@@ -0,0 +1,22 @@
angular.module('portal.common.directives.compareTo', ['ui.router'])
.directive('compareTo', function(){
return {
require: 'ngModel',
scope: {
otherModelValue: '=compareTo'
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
if ((modelValue === null || modelValue === undefined) && scope.otherModelValue === null) {
return true;
}
return modelValue === scope.otherModelValue;
};
scope.$watch('otherModelValue', function() {
ngModel.$validate();
});
}
};
});
@@ -0,0 +1,32 @@
(function() {
'use strict';
angular.module('portal.common.directives.permissions', ['ui.router'])
.directive('hasPermission', function(permissions){
return {
link: function(scope, element, attrs) {
if (!_.isString(attrs.hasPermission)){
throw 'hasPermission value must be a string';
}
var value = attrs.hasPermission.trim();
var notPermissionFlag = value[0] === '!';
if (notPermissionFlag) {
value = value.slice(1).trim();
}
function toggleVisibility() {
permissions.canView({permission: value}).then(function(allowed){
if ((allowed && !notPermissionFlag) || (!allowed && notPermissionFlag)) {
element.css('display', 'block');
} else {
element.css('display', 'none');
}
});
}
toggleVisibility();
scope.$on('permissionsChanged', toggleVisibility);
}
};
});
})();
@@ -0,0 +1,14 @@
<md-tabs md-selected="tabIndex" layout="column" layout-fill class="stretch-height">
<md-tab ng-repeat="tab in visibleTabs" md-on-select="processTabClick($event, tab, $index);" active="tab.active"layout="column" layout-fill>
<md-tab-label>
<div layout="row">
<div ng-bind-html="tab.leftItem"></div>
<span id="{{tab.title.toLowerCase()}}-tab">{{tab.title}}</span>
<div ng-bind-html="tab.rightItem"></div>
</div>
</md-tab-label>
<md-tab-body>
<div ng-include src="tab.source" style="height:100%"></div>
</md-tab-body>
</md-tab>
</md-tabs>
@@ -0,0 +1,129 @@
(function () {
'use strict';
var _$state;
/**
* Creates a tabset with a scrollable tab bar
* Based on the incredible example at http://www.bootply.com/l2ChB4vYmC
*/
angular.module('portal.common.directives.portalTabset', ['ui.router'])
.directive('portalTabSet', function ($state) {
_$state = $state;
return {
restrict: 'E',
replace: false, //Nothing shows up if you use replace: true
transclude: true,
scope: {
tabs: '=',
tabIndex: '=?',
},
templateUrl: 'common/directives/portal-tab-set/portal-tab-set.html',
link: repoTabsetLink
};
});
function repoTabsetLink(scope, element, attrs, fn) {
//The default starting position of the tab group.
var DEFAULT_TAB_POSITION = 0;
scope.tabIndex = scope.tabIndex === null || scope.tabIndex === undefined ? 0 : scope.tabIndex;
scope.visibleTabs = [];
scope.$watch('tabIndex', function(value) {
if (scope.tabIndex === null || scope.tabIndex === undefined) {
return;
}
scope.tabIndex = value;
});
scope.tabsetSelectChange = function(index) {
scope.tabIndex = index;
scope.$emit('tabsetSelectChange', index);
};
scope.$on('changeTabSelection', function(value) {
scope.tabIndex = value;
});
/**
* Determines if the state object for a tab is active.
*
* @param {type} state A tab's state
* @returns {boolean} True if the state is active, false otherwise.
*/
function isActive(state) {
var isState = _$state.is(state);
return isState || (_$state.current.name.indexOf(state) >= 0); // allow for sub tabs.
}
/**
* Updates the tabs after the state succesfully changes.
*
* @param {type} tabs An array of tabs. See action-pane.js for example
* @returns {undefined}
*/
function updateTabStates(tabs) {
//Update the active tag for each tab to reflect state change
var activeTab = false;
if (angular.isArray(tabs)) {
tabs.forEach(function (tab) {
tab.active = isActive(tab.state);
activeTab = activeTab || tab.active;
});
//If no tab has been specified, activate the first tab.
if (!activeTab && angular.isDefined(tabs[0])) {
tabs[0].default = true;
tabs[0].active = true;
}
//Now notify tabs to respect tab activation
scope.$broadcast('tabActivated');
}
}
scope.$on('tabsetDidChange', function (evt, tabs) {
scope.tabs = tabs;
update();
});
function update() {
updateVisisbleTabls();
updateTabStates(scope.tabs);
}
function updateVisisbleTabls() {
for (var i = 0; i < scope.tabs.length; i++) {
var tab = scope.tabs[i];
if (tab.visible === undefined || tab.visible) {
scope.visibleTabs[i] = tab;
}
}
}
scope.$on('$stateChangeSuccess', function () {
updateTabStates(scope.tabs);
});
/**
* Changes the state to the specified tab state. If the control key was
* held when the tab was click on, opens the tab's "big" state (fullscreen) in
* a new tab.
*
* @param {$event} evt The click event. Used to determine if ctrl/cmd was held
* during the click.
* @param {type} tab The tab to activate. A tab object from $scope.tabs.
*
* @returns {undefined}
*/
scope.processTabClick = function (evt, tab, index) {
_$state.go(tab.state);
update();
scope.tabsetSelectChange(index);
};
updateVisisbleTabls();
update();
} //end dcdTabsetLink function
})();
@@ -0,0 +1,3 @@
<div>
<i id="icon" class="material-icons" title="{{stats}}">{{iconImage}}</i>
</div>
@@ -0,0 +1,357 @@
angular.module('portal.common.directives.portalWebsocket', ['ui.router'])
.directive('portalWebsocket', PortalWebsocket);
function PortalWebsocket(Request, $timeout, portalUtils, PortalPubSub) {
return {
restrict: 'E',
templateUrl: 'common/directives/portal-websocket/portal-websocket.html',
link: function (scope) {
scope.iconImage = 'import_export';
scope.stats = 'not started';
var PingPong = function (msg) {
this.date = msg.date;
this.pull = msg.pull;
this.data = msg.data;
};
var Pinger = function () {
this.progress = 0;
this.count = 0;
this.iterations = null;
this.ping = null;
this.pong = null;
this.bwConvert = function (bytes, msec) {
var res = bytes / msec * 1000 * 8; // bits/second;
var units;
if (res > 1000000) {
res /= 1024000; // Mbits/sec
units = 'Mbps';
} else if (res > 1024) {
res /= 1000; // Kbits/sec
units = 'Kbps';
} else {
units = 'bps';
}
return this.round(res, 1) + units;
};
this.round = function (value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
};
this.isDone = function () {
if (this.count >= this.iterations) {
this.progress = 100;
return true;
} else {
this.progress = this.round(this.count / this.iterations * 100, 0);
return false;
}
};
return this;
};
var LatencyTask = portalUtils.inherit(function () {
Pinger.call(this);
this.iterations = 100;
this.latencySum = 0;
this.latencyMin = 0;
this.latencyAve = 0;
this.latencyMax = 0;
this.pps = 'n/a';
this.getPing = function () {
this.ping = new PingPong({'date': new Date().getTime(), 'pull': 0, 'data': []});
return this.ping;
};
this.onPong = function (pong) {
this.pong = pong;
this.count++;
var now = new Date().getTime();
var msec = now - this.pong.date;
this.latencySum += msec;
this.latencyAve = this.round(this.latencySum / this.count, 0);
if (this.latencyMin === 0 || msec < this.latencyMin) {
this.latencyMin = msec;
}
if (this.latencyMax === 0 || msec > this.latencyMax) {
this.latencyMax = msec;
}
// calc aggregate ppps
this.pps = this.count / this.latencySum * 1000;
this.pps = this.round(this.pps, 1);
return this.isDone();
};
return this;
}, Pinger);
var DownloadTask = portalUtils.inherit(function (latencyTask) {
Pinger.call(this);
this.iterations = 20;
this.downloadBytes = 0;
this.downloadTime = 0;
this.download = 0;
this.pull = 10000;
this.getPing = function () {
this.ping = new PingPong({'date': new Date().getTime(), 'pull': this.pull, 'data': []});
return this.ping;
};
this.onPong = function (pong) {
this.pong = pong;
this.count++;
var now = new Date().getTime();
var msec = now - this.pong.date - latencyTask.latencyAve / 2;
var bytes = this.pong.data.length;
this.downloadBytes += bytes;
this.downloadTime += msec;
// calc aggregate download bandwidth
this.download = this.bwConvert(this.downloadBytes, this.downloadTime);
return this.isDone();
};
return this;
}, Pinger);
var UploadTask = portalUtils.inherit(function (latencyTask, downloadTask) {
Pinger.call(this);
this.iterations = 20;
this.uploadBytes = 0;
this.uploadTime = 0;
this.upload = 0;
this.getPing = function () {
this.ping = new PingPong({'date': new Date().getTime(), 'pull': 0, 'data': downloadTask.pong.data});
return this.ping;
};
this.onPong = function (pong) {
this.pong = pong;
this.count++;
var now = new Date().getTime();
var msec = now - this.pong.date - latencyTask.latencyAve / 2;
var bytes = this.ping.data.length;
this.uploadBytes += bytes;
this.uploadTime += msec;
this.upload = this.bwConvert(this.uploadBytes, this.uploadTime);
return this.isDone();
};
return this;
}, Pinger);
var icon = document.getElementById('icon');
var latencyTask = new LatencyTask();
var downloadTask = new DownloadTask(latencyTask);
var uploadTask = new UploadTask(latencyTask, downloadTask);
var task = latencyTask;
var transport = null;
var stompClient = null;
var subscription = null;
function onConnectionSuccess(frame) {
transport = stompClient.ws.transport;
// subscribe to the /info/pong queue for this user, requires controller annotations:
// @SubscribeMapping('/info/ping')
// @SendToUser('/queue/info/pong')
var headers = {/*ack: 'client'*/};
subscription = stompClient.subscribe('/user/queue/pong', onPong, headers);
// if not websocket scale down the number of iterations
if (transport !== 'websocket') {
var div = 5;
latencyTask.iterations /= div;
downloadTask.iterations /= div;
uploadTask.iterations /= div;
}
// kick it off
task = latencyTask;
sendPing();
}
function onPong(frame) {
// frame.ack();
scope.$apply(function () {
var done = task.onPong(new PingPong(JSON.parse(frame.body)));
// switch tasks when finished
if (done && task === latencyTask) {
task = downloadTask;
} else if (done && task === downloadTask) {
task = uploadTask;
} else if (done && task === uploadTask) {
task = null;
}
if (task !== null) {
sendPing();
} else {
finish();
}
});
}
scope.busy = function () {
return task !== null;
};
function connect(transports) {
// create stomp client
var options = {transports: transports};
var socket = new SockJS(Request.baseURI + '/ws/stomp', null, options);
stompClient = Stomp.over(socket);
stompClient.debug = null;
// connect to server
scope.stats = 'connecting';
var headers = {};
stompClient.connect(headers, onConnectionSuccess, onConnectionFailure);
}
function sendPing() {
setActiveStatus();
stompClient.send('/start/ping', {}, JSON.stringify(task.getPing()));
}
var timer = null;
function flash() {
icon.style.color = (icon.style.color === 'green') ? 'goldenrod' : 'green';
if (getProgress() < 100) {
timer = $timeout(flash, 250);
}
}
function getProgress() {
return Math.round((latencyTask.progress + uploadTask.progress + downloadTask.progress) / 3);
}
function finish() {
$timeout.cancel(timer);
// shutdown the websocket connection
subscription.unsubscribe();
stompClient.disconnect();
stompClient = null;
if (transport === 'websocket') {
setSuccessfulStatus();
} else {
setDegradedStatus();
}
}
function onConnectionFailure(error) {
$timeout.cancel(timer);
stompClient = null; // Stomp connections are closed on failure
setFailureStatus(error.toString());
}
function createStats() {
var min = latencyTask.latencyMin;
var ave = latencyTask.latencyAve;
var max = latencyTask.latencyMax;
var pps = latencyTask.pps;
var upload = uploadTask.upload;
var download = downloadTask.download;
var latency = min + '/' + ave + '/' + max;
// always start with the transport
var stats = transport;
if (latencyTask.progress > 0) {
stats += ', ' + latency + 'ms, ' + pps + 'pps';
}
if (downloadTask.progress > 0) {
stats += ', ' + download;
}
if (uploadTask.progress > 0) {
stats += '/' + upload;
}
if (getProgress() < 100) {
stats += ', ' + getProgress() + '%';
}
return stats;
}
function setActiveStatus() {
// make available to html
scope.stats = createStats();
// icon stays flashing
// notify login dialog that we are not finished
PortalPubSub.publish('StompTestStatus', {status: 'active', stats: scope.stats});
}
// green
function setSuccessfulStatus() {
// make available to html
scope.stats = createStats();
// flashing has stopped, set green check
scope.iconImage = 'check';
icon.style.color = 'green';
// publish status (to login dialog)
PortalPubSub.publish('StompTestStatus', {status: 'successful', stats: scope.stats});
}
// yellow
function setDegradedStatus() {
// make available to html
scope.stats = createStats();
// flashing has stopped, set yellow info flag
scope.iconImage = 'info';
icon.style.color = 'goldenrod';
// publish status (to login dialog)
PortalPubSub.publish('StompTestStatus', {status: 'degraded', stats: scope.stats});
}
//red
function setFailureStatus(msg) {
// set hover over
scope.stats = 'failed: ' + msg;
// flashing has stopped, set red error flag
scope.iconImage = 'error';
icon.style.color = 'red';
// publish status (to login dialog)
PortalPubSub.publish('StompTestStatus', {status: 'failure', stats: scope.stats});
}
// start the test
flash();
var transports = [/*'websocket', 'xhr-streaming', 'eventsource', 'xhr-polling', 'jsonp-polling'*/];
connect(transports);
}
};
}
@@ -0,0 +1,9 @@
(function (module) {
'use strict';
module('portal.common.factories.pubsub', []).factory('PortalPubSub', [function () {
/*jshint ignore:start*/
var pub = new PubSub();
return pub;
/*jshint ignore:end*/
}]);
}(angular.module));
@@ -0,0 +1,91 @@
<md-dialog flex="40">
<form name="credForm" ng-submit="credForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Credential Name</label>
<input ng-model="credentials.name" name="credName" id="credName" required>
<div ng-messages="credForm.credName.$error" ng-show="credForm.credName.$invalid && submitted || credForm.credName.$touched">
<div ng-message="required">Credentials name is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Credential Type</label>
<md-select ng-model="credentials.credentialType" required name="type" id="type">
<md-option ng-repeat="cred in credentialTypes" ng-value="cred.name">{{cred.value}}</md-option>
</md-select>
<div ng-messages="credForm.type.$error" ng-show="credForm.type.$invalid && submitted || credForm.type.$touched">
<div ng-message="required">Credential type is required</div>
</div>
</md-input-container>
</div>
</div>
<div layout-gt-xs="row" layout-align="start center" ng-if="credentials.credentialType === 'PASSWD'">
<md-input-container class="md-block" flex-gt-sm>
<label>User Name</label>
<input ng-model="credentials.username" required name="username" id="username">
<div ng-messages="credForm.username.$error" ng-show="credForm.username.$invalid && submitted || credForm.username.$touched">
<div ng-message="required">Username is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>Password</label>
<input ng-model="credentials.password" type="{{passwordType}}" name="password" id="password" ng-required="requirePassword">
<div ng-messages="credForm.password.$error" ng-show="credForm.password.$invalid && submitted || credForm.password.$touched">
<div ng-message="required">Password is required</div>
</div>
</md-input-container>
<md-button class="md-icon-button" style="margin-bottom: 25px;" ng-mousedown="passwordType='text'" ng-mouseup="passwordType='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
<div layout="column" ng-if="credentials.credentialType === 'SSH'" flex>
<md-input-container class="md-block" flex-gt-sm>
<label>User Identity</label>
<input ng-model="credentials.username" required name="username" id="username">
<div ng-messages="credForm.username.$error" ng-show="credForm.username.$invalid && submitted || credForm.username.$touched">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Username on the remote system the ssh key belongs to</md-tooltip>
<div ng-message="required">User identity is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<label>SSH Private Key</label>
<textarea ng-model="credentials.key" name="sshKey" id="sshKey" required rows="3" cols="50"></textarea>
<div ng-messages="credForm.sshKey.$error" ng-show="credForm.sshKey.$invalid && submitted || credForm.sshKey.$touched">
<div ng-message="required">SSH Key is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex>
<label>Passphrase</label>
<input ng-model="credentials.passphrase" name="passphrase" id="passphrase">
</md-input-container>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,60 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addCreds', ['ui.router']).controller('AddCredsCtrl', AddUserCtrlController);
function AddUserCtrlController($scope, modalInstance, $state, cache, $mdDialog, Account, Credentials, credentialStores, credentialProvider, portalUtils) {
$scope.header = modalInstance.header;
$scope.passwordType = 'password';
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.credentials === undefined ? true : false;
$scope.credentials = $scope.isNew ? new Credentials() : modalInstance.credentials;
$scope.valid = false;
$scope.mCache = cache.request([new credentialStores.CredentialTypes()]).then(function(){
$scope.credentialTypes = $scope.mCache.credentialTypes.data.values;
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
credentialProvider.addCredentials($scope.credentials).then(function(data){
$scope.loadingBlock = false;
portalUtils.toast('Credentials ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err){
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end AddUserCtrlController function
})();
@@ -0,0 +1,32 @@
<md-dialog flex="25">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}} to {{currentDir}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<div layout="row" flex="100" class="md-dialog-content">
<md-input-container flex>
<label>File Directory Location</label>
<input type="text" id="fileName" ng-model="model.fileDir" required>
</md-input-container>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger text-center">{{error}}</div>
<md-button id="okButton" class="md-raised md-primary" ng-click="ok()" ng-disabled="!valid">OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,67 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addDirectory', ['ui.router'])
.controller('AddDirectoryCtrl', AddDirectoryCtrlController);
function AddDirectoryCtrlController($scope, modalInstance, $state, cache, $mdDialog, fileProvider, UploadFile, portalUtils) {
$scope.header = modalInstance.header;
$scope.currentDir = modalInstance.currentDir;
$scope.loadingBlock = false;
$scope.model = { };
$scope.valid = false;
$scope.$watch('model', function(){
if ($scope.model.fileDir === undefined) {
$scope.valid = false;
return;
}
$scope.valid = true;
}, true);
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
fileProvider.makeDirectory($scope.currentDir, $scope.model.fileDir).then(function(data) {
$scope.loadingBlock = false;
portalUtils.toast('Directory added successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
$scope.$on('$destroy', function () {
if ($scope.mCache !== undefined) {
$scope.mCache.unlisten();
}
});
} //end AddDirectoryCtrlController function
})();
@@ -0,0 +1,39 @@
<md-dialog>
<form name="emailTmplForm" ng-submit="emailTmplForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div layout="column" layout-align="start start" flex>
<md-input-container class="md-block" flex-gt-sm>
<label>Email Template Name</label>
<input ng-model="emailTmpl.emailName" required id="emailTmpl" name="emailTmpl">
<div ng-messages="emailTmplForm.emailTmpl.$error" ng-show="emailTmplForm.emailTmpl.$invalid && submitted || emailTmplForm.emailTmpl.$touched">
<div ng-message="required">Email template name is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-sm>
<label>Email Subject</label>
<input ng-model="emailTmpl.emailSubject" required id="emailSubject" name="emailSubject">
<div ng-messages="emailTmplForm.emailSubject.$error" ng-show="emailTmplForm.emailSubject.$invalid && submitted || emailTmplForm.emailSubject.$touched">
<div ng-message="required">Email subject is required</div>
</div>
</md-input-container>
<span><strong>Email Body</strong></span>
<textarea ui-tinymce="tinymceOptions" ng-model="emailTmpl.emailMessage"></textarea>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,67 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addEmailTmpl', ['ui.router']).controller('AddEmailTmplCtrl', addEmailTmplCtrlController);
function addEmailTmplCtrlController($scope, modalInstance, $state, cache, $mdDialog, EmailTemplate,
systemProvider, scriptStores, portalUtils, $timeout) {
$scope.trustAsHtml = portalUtils.trustAsHtml;
$scope.header = modalInstance.header;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.template === undefined;
$scope.emailTmpl = $scope.isNew ? new EmailTemplate() : new EmailTemplate(modalInstance.template);
/*jshint ignore:start*/
$scope.tinymceOptions = {
inline: false,
skin: 'lightgray',
theme : 'modern',
branding: false,
height: 300,
max_height: 300,
width: 600,
max_width: 600,
resize: false
};
/*jshint ignore:end*/
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'Added': 'Edited';
systemProvider.addEmailTemplate($scope.emailTmpl).then(function(data){
portalUtils.toast('Email Template ' + status + ' Successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end addEmailTmplCtrlController function
})();
@@ -0,0 +1,50 @@
<md-dialog flex="40">
<form name="envForm" ng-submit="envForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<md-button class="md-icon-button" ng-click="addEnvVar()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">New Environment Variable</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-list flex>
<md-list-item ng-repeat="param in envVars" class="secondary-button-padding">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<div layout="row" flex>
<md-input-container flex>
<label>Variable Name</label>
<input type="text" ng-model="param.name" class="answerInput" required/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Variable Value</label>
<input type="text" ng-model="param.value" class="answerInput" required/>
</md-input-container>
</div>
<div layout="column" flex="10">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="delete($index, envVars)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Environment Variable</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
</md-list-item>
</md-list>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,86 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addEnvVars', ['ui.router']).controller('AddEnvVarCtrl', addEnvVarCtrlController);
function addEnvVarCtrlController($scope, modalInstance, cache, $mdDialog, scriptObjects,
systemProvider, systemStores, portalUtils) {
$scope.header = modalInstance.header;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.envVars.length === 0;
$scope.envVars = [];
if (!$scope.isNew) {
for (var i = 0; i < modalInstance.envVars.length; i++) {
$scope.envVars.push( new scriptObjects.ScriptEnvironmentVariable(modalInstance.envVars[i]) );
}
}
$scope.valid = false;
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
systemProvider.addEnvVars($scope.envVars).then(function(data) {
$scope.loadingBlock = false;
portalUtils.toast('Script ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
$scope.addEnvVar = function() {
var env = new scriptObjects.ScriptEnvironmentVariable();
$scope.envVars.push(env);
};
$scope.moveUp = function(index, array) {
var ent1 = array[index];
var ent2 = array[index-1];
array[index] = ent2;
array[index-1] = ent1;
};
$scope.moveDown = function(index, array) {
var ent1 = array[index];
var ent2 = array[index+1];
array[index] = ent2;
array[index+1] = ent1;
};
$scope.delete = function (id, array) {
array.splice(id, 1);
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end addEnvVarCtrlController function
})();
@@ -0,0 +1,74 @@
<md-dialog flex="40">
<form name="gitForm" ng-submit="gitForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>
<input ng-model="git.name" name="name" id="name" required>
<div ng-messages="gitForm.name.$error" ng-show="gitForm.name.$invalid && submitted || gitForm.name.$touched">
<div ng-message="required">Name is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Git SCM Url</label>
<input ng-model="git.scm" name="scm" id="scm" required>
<div ng-messages="gitForm.scm.$error" ng-show="gitForm.scm.$invalid && submitted || gitForm.scm.$touched">
<div ng-message="required">Git SCM url is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Git Branch</label>
<input ng-model="git.branch" name="branch" id="branch" required>
<div ng-messages="gitForm.branch.$error" ng-show="gitForm.branch.$invalid && submitted || gitForm.branch.$touched">
<div ng-message="required">Git SCM url is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Local Checkout Directory</label>
<input ng-model="git.directory" name="directory" id="directory" required>
<div ng-messages="gitForm.directory.$error" ng-show="gitForm.directory.$invalid && submitted || gitForm.directory.$touched">
<div ng-message="required">Checkout directory is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Credentials</label>
<md-select ng-model="git.credentials" required name="creds" id="creds" ng-model-options="{trackBy: '$value.uid'}">
<md-option ng-repeat="cred in credentials" ng-value="cred">{{displayKey(cred)}}</md-option>
</md-select>
<div ng-messages="credForm.creds.$error" ng-show="credForm.creds.$invalid && submitted || credForm.creds.$touched">
<div ng-message="required">Credentials are required</div>
</div>
</md-input-container>
</div>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,67 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addGit', ['ui.router']).controller('AddGitCtrl', addGitCtrlController);
function addGitCtrlController($scope, modalInstance, $state, cache, $mdDialog, GitInfo, Account, accountProvider, gitProvider, credentialStores, portalUtils) {
$scope.trustAsHtml = portalUtils.trustAsHtml;
$scope.header = modalInstance.header;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.gitInfo === undefined ? true : false;
$scope.git = $scope.isNew ? new GitInfo() : modalInstance.gitInfo;
$scope.valid = false;
$scope.mCache = cache.request([new credentialStores.Credentials()]).then(function(){
$scope.credentials = $scope.mCache.credentials.data.values;
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
gitProvider.addGitRepo($scope.git).then(function(data){
$scope.loadingBlock = false;
portalUtils.toast('Git ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err){
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
$scope.displayKey = function(cred) {
if (cred === undefined) {
return '';
}
return cred.name + (cred.credentialType === 'SSH' ? ' (SSH Key)' : ' (Username/Password)');
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end addGitCtrlController function
})();
@@ -0,0 +1,67 @@
<md-dialog flex>
<form name="permForm" ng-submit="permForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div>
<div layout="row">
<md-input-container class="md-block" flex-gt-xs ng-if="isNew">
<label>Permission Group Unique Name</label>
<input ng-model="permission.name" name="name" id="name" required>
<div ng-messages="permForm.name.$error" ng-show="permForm.name.$invalid && submitted || permForm.name.$touched">
<div ng-message="required">Unique name required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>Permission Group Display Name</label>
<input ng-model="permission.displayName" name="displayName" id="displayName" required>
<div ng-messages="permForm.displayName.$error" ng-show="permForm.displayName.$invalid && submitted || permForm.displayName.$touched">
<div ng-message="required">Display name required</div>
</div>
</md-input-container>
</div>
<div layout="row" flex>
<md-list>
<md-list-item>
<p flex>Permission Group Enabled</p>
<span flex="5"></span>
<md-switch md-invert ng-model="permission.enabled" class="md-primary">{{permission.enabled ? 'True' : 'False'}}</md-switch>
</md-list-item>
</md-list>
</div>
</div>
<div layout="row" flex>
<md-tabs md-dynamic-height flex>
<md-tab ng-repeat="cat in permissionCategories" label="{{cat.displayName}}">
<md-content class="md-padding" flex>
<md-list>
<md-list-item ng-repeat="perm in cat.permissions">
<p>{{perm.displayName}}</p>
<span flex="5"></span>
<md-switch ng-model="perm.allowed" class="md-primary">{{perm.allowed ? 'Enabled' : 'Disabled'}}</md-switch>
</md-list-item>
</md-list>
</md-content>
</md-tab>
</md-tabs>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,92 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addPermission', ['ui.router']).controller('AddPermissionCtrl', AddPermissionCtrlController);
function AddPermissionCtrlController($scope, modalInstance, $state, cache, $mdDialog, permissionObjects,
permissionStores, permissionProvider, portalUtils) {
$scope.header = modalInstance.header;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.permission === undefined ? true : false;
$scope.permission = $scope.isNew ? new permissionObjects.PermissionGroup() : new permissionObjects.PermissionGroup(modalInstance.permission);
$scope.valid = false;
$scope.permissionCategories = [];
$scope.mCache = cache.request([new permissionStores.PermissionCategories()]).then(function(){
$scope.permissionCategories = $scope.mCache.permissionCategories.data.values;
if (!$scope.isNew) {
$.each($scope.permission.permissions, function(key, value) {
for (var i = 0; i < $scope.permissionCategories.length; i++) {
var cat = $scope.permissionCategories[i];
if (cat.name !== value.permissionCategory) {
continue;
}
for (var j = 0; j < cat.permissions.length; j++) {
var perm = cat.permissions[j];
if (value.permissionId === perm.id) {
perm.allowed = value.allowed;
}
}
}
});
}
}).catch(function(err){
portalUtils.toast('Unable to get permission categories: ' + err.message, ['top', 'left'], 2000);
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
$scope.permission.permissions = [];
$.each($scope.permissionCategories, function(key, cat) {
$.each(cat.permissions, function(key2, perm) {
var newPerm = new permissionObjects.PermissionGroupPermission({
permissionId: perm.id,
permissionGroupId: $scope.permission.id,
name: perm.name,
displayName: perm.displayName,
allowed: perm.allowed === undefined ? false : perm.allowed
});
$scope.permission.permissions.push(newPerm);
});
});
permissionProvider.updatePermissions($scope.isNew, $scope.permission).then(function(results) {
$scope.loadingBlock = false;
portalUtils.toast('Permission ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err){
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end AddPermissionCtrlController function
})();
@@ -0,0 +1,63 @@
<md-card>
<md-card-content>
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>Schedule</strong></span>
<span flex></span>
<md-button class="md-icon-button" ng-click="addSchedule()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">New Schedule</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
</div>
</md-toolbar>
</div>
<div layout="row" flex="100">
<md-list flex>
<md-list-item ng-repeat="sched in script.schedule" class="secondary-button-padding" ng-if="sched.frequency !== 'NOW' && sched.frequency !== 'TRIGGERED'">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<md-input-container flex>
<label>Frequency</label>
<md-select ng-model="sched.frequency" required>
<md-option ng-repeat="sched in schedFreq" ng-value="sched.name" ng-if="sched.name !== 'NOW' && sched.name !== 'TRIGGERED'">{{sched.value}}</md-option>
</md-select>
</md-input-container>
<md-input-container flex>
<label >Start Date/Time</label>
<input mdc-datetime-picker="" date="true" time="true" type="text" id="startdatetime"
show-todays-date="" minutes="true" min-date="date" show-icon="true" format='MMM D, YYYY h:mm:ss A'
ng-model="sched.startDatetime" class=" dtp-no-msclear dtp-input">
</md-input-container>
<md-input-container flex ng-if="sched.frequency !== 'SPECIFIC'" >
<label style="padding-left: 35px;">End Date/Time</label>
<input mdc-datetime-picker="" date="true" time="true" type="text" id="enddatetime"
show-todays-date="" minutes="true" min-date="date" show-icon="true" format='MMM D, YYYY h:mm:ss A'
ng-model="sched.endDatetime" class=" dtp-no-msclear dtp-input md-input">
</md-input-container>
<md-input-container ng-if="sched.frequency !== 'SPECIFIC'">
<label>Number of Executions</label>
<input type="number" min="0" ng-model="sched.maxExecutions"/>
</md-input-container>
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="moveUp($index, script.schedule)" ng-if="($index > 0)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Up</md-tooltip>
<md-icon>arrow_upward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-if="($index < script.schedule.length-1) &&
(script.schedule[$index + 1] !== undefined &&
script.schedule[$index + 1].frequency != 'NOW' &&
script.schedule[$index + 1].frequency != 'TRIGGERED')" ng-click="moveDown($index, script.schedule)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Down</md-tooltip>
<md-icon>arrow_downward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-click="delete($index,script.schedule)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Parameter</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</md-list-item>
</md-list>
</div>
</md-card-content>
</md-card>
@@ -0,0 +1,9 @@
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Command</label>
<input ng-model="script.command" name="scm" id="scm" required>
<div ng-messages="scriptForm.scm.$error" ng-show="scriptForm.scm.$invalid && submitted || scriptForm.scm.$touched">
<div ng-message="required">Script command is required</div>
</div>
</md-input-container>
</div>
@@ -0,0 +1,27 @@
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>Credentials</strong></label>
<md-select ng-model="script.remote.scriptCredentials" required name="creds" id="creds" ng-model-options="{trackBy: '$value.uid'}">
<md-option ng-repeat="cred in credentials" ng-value="cred">{{displayKey(cred)}}</md-option>
</md-select>
<div ng-messages="scriptForm.creds.$error" ng-show="scriptForm.creds.$invalid && submitted || scriptForm.creds.$touched">
<div ng-message="required">Credentials are required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>SSH URL</strong></label>
<input ng-model="script.remote.url" name="url" id="url" required>
<div ng-messages="scriptForm.url.$error" ng-show="scriptForm.url.$invalid && submitted || scriptForm.url.$touched">
<div ng-message="required">SSH URL is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label><strong>SSH Port</strong></label>
<input ng-model="script.remote.port" type="number" min="0" max="65535" name="port" id="port" required>
<div ng-messages="scriptForm.port.$error" ng-show="scriptForm.port.$invalid && submitted || scriptForm.port.$touched">
<div ng-message="required">SSH URL is required</div>
</div>
</md-input-container>
</div>
@@ -0,0 +1,78 @@
<div layout-gt-xs="row">
<md-checkbox ng-model="model.fromLocal" ng-change="fromLocalChange()" class="md-primary">
From Local
</md-checkbox>
</div>
<div layout-gt-xs="row" ng-if="!model.fromLocal">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>From Host</strong></label>
<input ng-model="script.scp.fromHost" name="fromHost" id="fromHost" required>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Host name of the machine script is copying from. For local type 'LOCAL'</md-tooltip>
<div ng-messages="scriptForm.fromHost.$error" ng-show="scriptForm.fromHost.$invalid && submitted || scriptForm.fromHost.$touched">
<div ng-message="required">From host address is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label><strong>From Port</strong></label>
<input ng-model="script.scp.fromPort" type="number" min="0" max="65535" name="fromPort" id="fromPort" required>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Host port of the machine script is copying from. For local type '0'</md-tooltip>
<div ng-messages="scriptForm.fromPort.$error" ng-show="scriptForm.fromPort.$invalid && submitted || scriptForm.fromPort.$touched">
<div ng-message="required">From Port is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row" ng-if="!model.fromLocal">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>From Credentials</strong></label>
<md-select ng-model="script.scp.fromCredentials" required name="fromCredentials" id="fromCredentials" ng-model-options="{trackBy: '$value.uid'}">
<md-option ng-repeat="cred in credentials" ng-value="cred">{{displayKey(cred)}}</md-option>
</md-select>
<div ng-messages="scriptForm.fromCredentials.$error" ng-show="scriptForm.fromCredentials.$invalid && submitted || scriptForm.fromCredentials.$touched">
<div ng-message="required">From credentials are required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-checkbox ng-model="model.toLocal" ng-change="toLocalChange()" class="md-primary">
To Local
</md-checkbox>
</div>
<div layout-gt-xs="row" ng-if="!model.toLocal">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>To Host</strong></label>
<input ng-model="script.scp.toHost" name="toHost" id="toHost" required>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Host name of the machine script is copying to. For local type 'LOCAL'</md-tooltip>
<div ng-messages="scriptForm.toHost.$error" ng-show="scriptForm.toHost.$invalid && submitted || scriptForm.toHost.$touched">
<div ng-message="required">To host address is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label><strong>SSH Port</strong></label>
<input ng-model="script.scp.toPort" type="number" min="0" max="65535" name="toPort" id="toPort" required>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Host port of the machine script is copying to. For local type '0'</md-tooltip>
<div ng-messages="scriptForm.toPort.$error" ng-show="scriptForm.toPort.$invalid && submitted || scriptForm.toPort.$touched">
<div ng-message="required">To Port is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row" ng-if="!model.toLocal">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>To Credentials</strong></label>
<md-select ng-model="script.scp.toCredentials" required name="toCredentials" id="toCredentials" ng-model-options="{trackBy: '$value.uid'}">
<md-option ng-repeat="cred in credentials" ng-value="cred">{{displayKey(cred)}}</md-option>
</md-select>
<div ng-messages="scriptForm.toCredentials.$error" ng-show="scriptForm.toCredentials.$invalid && submitted || scriptForm.toCredentials.$touched">
<div ng-message="required">From credentials are required</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>File name or regex for file</strong></label>
<input ng-model="script.scp.dataRegex" name="dataRegex" id="dataRegex" required>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">File name or regular expression for file to send'</md-tooltip>
<div ng-messages="scriptForm.dataRegex.$error" ng-show="scriptForm.dataRegex.$invalid && submitted || scriptForm.dataRegex.$touched">
<div ng-message="required">File name or regular expression required</div>
</div>
</md-input-container>
</div>
@@ -0,0 +1,55 @@
<md-card>
<md-card-content>
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>Script</strong></span>
<span flex></span>
</div>
</md-toolbar>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label><strong>Script Name</strong></label>
<input ng-model="script.name" name="name" id="name" required>
<div ng-messages="scriptForm.name.$error" ng-show="scriptForm.name.$invalid && submitted || scriptForm.name.$touched">
<div ng-message="required">Name is required</div>
</div>
</md-input-container>
</div>
<md-input-container class="md-block" flex-gt-xs>
<label><strong>Script Type</strong></label>
<md-select ng-model="script.scriptType" required name="scriptType" id="scriptType">
<md-option ng-repeat="st in scriptTypes" ng-value="st.name">{{st.value}}</md-option>
</md-select>
<div ng-messages="scriptForm.scriptType.$error" ng-show="scriptForm.scriptType.$invalid && submitted || scriptForm.scriptType.$touched">
<div ng-message="required">Script type is required</div>
</div>
</md-input-container>
<div layout-gt-xs="column" ng-switch="script.scriptType">
<div ng-switch-when="LOCAL">
<div ng-include src ="'common/partials/add-script/add-script-left-local.html'" flex></div>
</div>
<div ng-switch-when="REMOTE">
<div ng-include src ="'common/partials/add-script/add-script-left-remote.html'" flex></div>
</div>
<div ng-switch-when="SCP">
<div ng-include src ="'common/partials/add-script/add-script-left-scp.html'" flex></div>
</div>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Base Directory</label>
<input ng-model="script.baseDirectory" name="bd" id="bd">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="bottom">Base directory to find files in</md-tooltip>
</md-input-container>
</div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Output Directory</label>
<input ng-model="script.outputDirectory" name="od" id="od">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Directory to send/save the files to</md-tooltip>
</md-input-container>
</div>
</md-card-content>
</md-card>
@@ -0,0 +1,60 @@
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>Script Chain</strong></span>
<span flex></span>
<md-button class="md-icon-button" ng-click="addScriptChain()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">New Script Chain</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
</div>
</md-toolbar>
</div>
<div layout="row" flex="100">
<md-list flex>
<md-list-item ng-repeat="chain in script.scriptChain" class="secondary-button-padding">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<div layout="row" flex>
<md-input-container class="md-block" flex>
<label>Scripts</label>
<md-select ng-model="chain.childScript" required name="chain_{{$index}}" id="chain_{{$index}}" ng-model-options="{trackBy: '$value'}" flex>
<md-option ng-repeat="s in availScripts" ng-value="s.id" ng-if="s.name !== script.name">{{s.name}}</md-option>
</md-select>
<div ng-messages="scriptForm['chain_' + $index].$error" ng-show="scriptForm['chain_' + $index].$invalid && submitted || scriptForm['chain_' + $index].$touched">
<div ng-message="required">Script Required</div>
</div>
</md-input-container>
<md-input-container flex>
<label>Exit Status</label>
<input type="number" ng-model="chain.exitStatus" class="answerInput" required name="exitStatus_{{$index}}" id="exitStatus_{{$index}}"/>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Exit status of the parent script to execute this script</md-tooltip>
<div ng-messages="scriptForm['exitStatus_' + $index].$error" ng-show="scriptForm['exitStatus_' + $index].$invalid && submitted || scriptForm['exitStatus_' + $index].$touched">
<div ng-message="required">Exit Status is Required</div>
</div>
</md-input-container>
<md-input-container flex>
<label>Exec After N Mins</label>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">(Optional) How many minutes after the parent script ends should this script execute</md-tooltip>
<input type="number" ng-model="chain.executeAfterMin" class="answerInput"/>
</md-input-container>
</div>
<div layout="column" flex="25">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="moveUp($index, script.scriptChain" ng-if="($index > 0)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Up</md-tooltip>
<md-icon>arrow_upward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-if="($index < script.scriptChain.length-1)" ng-click="moveDown($index, script.scriptChain)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Down</md-tooltip>
<md-icon>arrow_downward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-click="delete($index, script.scriptChain)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Parameter</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
</md-list-item>
</md-list>
</div>
@@ -0,0 +1,89 @@
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>Script Email</strong></span>
<span flex></span>
<md-button class="md-icon-button" ng-click="addScriptEmail()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">New Script Email</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
</div>
</md-toolbar>
</div>
<div layout="column" flex="100">
<div layout="row" ng-if="model.addEmail" flex>
<div layout="row" layout-align="start center" flex>
<md-input-container class="md-block" flex>
<label>Email Template</label>
<md-select ng-model="model.email" required name="email_{{$index}}" id="email_{{$index}}" flex>
<md-option ng-repeat="tmpl in emails" ng-value="tmpl">{{tmpl.emailName}}</md-option>
</md-select>
<div ng-messages="scriptForm['email_' + $index].$error" ng-show="scriptForm['email_' + $index].$invalid && submitted || scriptForm['email_' + $index].$touched">
<div ng-message="required">Email Template Required</div>
</div>
</md-input-container>
<md-button class="md-icon-button" ng-click="addRecipient(model)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Add Recipient</md-tooltip>
<md-icon>add</md-icon>
</md-button>
</div>
<md-list flex>
<md-list-item ng-repeat="recip in model.recipients track by $index">
<div layout="row" layout-align="start start" flex>
<md-input-container class="md-block" flex>
<label>Recipient</label>
<md-select ng-model="recip" required name="recip_{{$index}}_{{$parent.$index}}" id="recip_{{$index}}_{{$parent.$index}}" ng-change="userUpdate(model, recip, $index)" flex>
<md-option ng-repeat="u in users track by $index" ng-value="u">{{u.username}}</md-option>
</md-select>
<div ng-messages="scriptForm['recip_' + $index + '_' + $parent.$index].$error"
ng-show="scriptForm['recip_' + $index + '_' + $parent.$index].$invalid && submitted || scriptForm['recip_' + $index + '_' + $parent.$index].$touched">
<div ng-message="required">Recipient Required</div>
</div>
</md-input-container>
</div>
</md-list-item>
</md-list>
<div layout="column" flex="25">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="confirmTemplate()" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Confirm Email Template</md-tooltip>
<md-icon>check</md-icon>
</md-button>
<md-button class="md-icon-button" ng-click="removeTmpl()" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Email Template</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
<md-list flex>
<md-list-item ng-repeat="email in script.scriptEmails track by $index" class="secondary-button-padding">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<div layout="row" layout-align="start center" flex>
<md-input-container class="md-block" flex>
<label>Email Template</label>
<input ng-value="email.emailName" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
</div>
<md-list flex>
<md-list-item ng-repeat="recip in email.recipients track by $index">
<div layout="row" layout-align="start start" flex>
<md-input-container class="md-block" flex>
<label>Recipient</label>
<input ng-value="recip.username" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
</div>
</md-list-item>
</md-list>
<div layout="column" flex="25">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="delete($index, script.scriptEmails)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Email Template</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
</md-list-item>
</md-list>
</div>
@@ -0,0 +1,47 @@
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>Script Environment Variables</strong></span>
<span flex></span>
<md-button class="md-icon-button" ng-click="addEnvVar()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">New Script Environment Variable</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
</div>
</md-toolbar>
</div>
<div layout="row" flex="100">
<md-list flex>
<md-list-item ng-repeat="param in script.scriptVariables" class="secondary-button-padding">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<div layout="row" flex>
<md-input-container flex>
<label>Variable Name</label>
<input type="text" ng-model="param.name" class="answerInput"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Variable Value</label>
<input type="text" ng-model="param.value" class="answerInput"/>
</md-input-container>
</div>
<div layout="column" flex="25">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="moveUp($index, script.scriptVariables)" ng-if="($index > 0)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Up</md-tooltip>
<md-icon>arrow_upward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-if="($index < script.scriptVariables.length-1)" ng-click="moveDown($index, script.scriptVariables)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Down</md-tooltip>
<md-icon>arrow_downward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-click="delete($index, script.scriptVariables)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Parameter</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
</md-list-item>
</md-list>
</div>
@@ -0,0 +1,41 @@
<div layout="row" flex="100">
<md-toolbar class="md-padding md-portal-grey">
<div layout="row" layout-align="center center" flex="100">
<span><strong>{{script.scriptType !== 'LOCAL' ? 'Commands' : 'Parameters'}}</strong></span>
<span flex></span>
<md-button class="md-icon-button" ng-click="addParameter()">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">{{script.scriptType !== 'LOCAL' ? 'New Command' : 'New Parameter'}}</md-tooltip>
<md-icon class="md-icon-default-color">note_add</md-icon>
</md-button>
</div>
</md-toolbar>
</div>
<div layout="row" flex="100">
<md-list flex>
<md-list-item ng-repeat="param in script.parameters" class="secondary-button-padding">
<div layout="row" flex="100" style="background: {{$index % 2 === 0 ? 'white' : '#DCDCDC'}}; padding-left:5px; padding-right:5px;">
<div layout="column" flex>
<md-input-container flex md-no-float>
<input type="text" ng-model="param.parameter" class="answerInput"/>
</md-input-container>
</div>
<div layout="column" flex="25">
<div layout="row" layout-align="end center" flex>
<md-button class="md-icon-button" ng-click="moveUp($index, script.parameters)" ng-if="($index > 0)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Up</md-tooltip>
<md-icon>arrow_upward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-if="($index < script.parameters.length-1)" ng-click="moveDown($index, script.parameters)">
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Move Down</md-tooltip>
<md-icon>arrow_downward</md-icon>
</md-button>
<md-button class="md-icon-button" ng-click="delete($index,script.parameters)" >
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Remove Parameter</md-tooltip>
<md-icon>delete</md-icon>
</md-button>
</div>
</div>
</div>
</md-list-item>
</md-list>
</div>
@@ -0,0 +1,21 @@
<md-card ng-if="script.scriptType !== 'SCP'">
<md-card-content>
<div ng-include src ="'common/partials/add-script/add-script-right-parameters.html'"flex></div>
</md-card-content>
</md-card>
<md-card>
<md-card-content>
<div ng-include src ="'common/partials/add-script/add-script-right-chain.html'" flex></div>
</md-card-content>
</md-card>
<md-card>
<md-card-content ng-if="script.scriptType !== 'SCP'">
<div ng-include src ="'common/partials/add-script/add-script-right-env-vars.html'" flex></div>
</md-card-content>
</md-card>
<md-card ng-if="model.smtpEnabled">
<md-card-content>
<div ng-include src ="'common/partials/add-script/add-script-right-email.html'" flex></div>
</md-card-content>
</md-card>
<md-card>
@@ -0,0 +1,19 @@
.add-script-even {
background-color: #f3f3f3;
}
answerInput.md-input-container.md-input {
height: 65px !important;
}
.md-parameter-toolbar {
background-color: rgb(219, 233, 240) !important;
color: black !important;
padding-left: 5px !important;
padding-right: 5px !important;
}
.md-icon-default-color {
color: grey !important;
color: rgba(0, 0, 0, 0.54) !important;
}
@@ -0,0 +1,31 @@
<md-dialog flex="95">
<form name="scriptForm" ng-submit="scriptForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div layout="row" flex>
<div layout="column" flex="50" ng-include src="'common/partials/add-script/add-script-left.html'"></div>
<div layout="column" flex="50" ng-include src="'common/partials/add-script/add-script-right.html'"></div>
</div>
<div ng-include src="'common/partials/add-script/add-script-bottom.html'"></div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,218 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addScript', ['ui.router']).controller('AddScriptCtrl', addScriptCtrlController);
function addScriptCtrlController($scope, modalInstance, $state, cache, $mdDialog, scriptObjects, EmailTemplate, Account,
scriptProvider, scriptStores, credentialStores, portalUtils, systemStores, accountStores) {
$scope.trustAsHtml = portalUtils.trustAsHtml;
$scope.header = modalInstance.header;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.script === undefined ? true : false;
$scope.script = $scope.isNew ? new scriptObjects.Script() : new scriptObjects.Script(modalInstance.script);
$scope.model = {
fromLocal: $scope.isNew || $scope.script.scriptType !== 'SCP' ? false : $scope.script.scp.fromHost === 'LOCAL',
toLocal: $scope.isNew || $scope.script.scriptType !== 'SCP' ? false : $scope.script.scp.toHost === 'LOCAL',
addEmail : false,
recipients: []
};
$scope.valid = false;
$scope.mCache = cache.request([
new scriptStores.ScriptTypes(),
new scriptStores.ScheduleFrequencies(),
new credentialStores.Credentials(),
new scriptStores.Scripts(),
new systemStores.EmailTemplates(),
new systemStores.SMTPConfig(),
new accountStores.UserPool()
]).then(function(){
$scope.scriptTypes = $scope.mCache.scriptTypes.data.values;
$scope.schedFreq = $scope.mCache.scheduleFrequencies.data.values;
$scope.credentials = $scope.mCache.credentials.data.values;
$scope.availScripts = $scope.mCache.scripts.data.values;
$scope.users = $scope.mCache.userPool.data.values;
$scope.emails = $scope.mCache.emailTmpls.data.values;
$.each($scope.mCache.smtpConfig.data.values, function(key, value){
if (value.name === 'smtp.enabled') {
$scope.model.smtpEnabled = value.value === 'true' || value.value === true;
return;
}
});
});
$scope.fromLocalChange = function() {
if ($scope.model.fromLocal) {
$scope.script.scp.fromHost = 'LOCAL';
$scope.script.scp.fromPort = 0;
$scope.script.scp.fromCredentials = $scope.credentials[0];
} else {
$scope.script.scp.fromHost = undefined;
$scope.script.scp.fromPort = undefined;
$scope.script.scp.fromCredentials = undefined;
}
};
$scope.toLocalChange = function() {
if ($scope.model.toLocal) {
$scope.script.scp.toHost = 'LOCAL';
$scope.script.scp.toPort = 0;
$scope.script.scp.toCredentials = $scope.credentials[0];
} else {
$scope.script.scp.toHost = undefined;
$scope.script.scp.toPort = undefined;
$scope.script.scp.toCredentials = undefined;
}
};
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
$.each($scope.script.schedule, function(index, value) {
$scope.script.schedule[index].startDatetime = convertTime(value.startDatetime);
$scope.script.schedule[index].endDatetime = convertTime(value.endDatetime);
$scope.script.schedule[index].lastRun = convertTime(value.lastRun);
});
scriptProvider.addScript($scope.script).then(function(data) {
$scope.loadingBlock = false;
portalUtils.toast('Script ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
function convertTime(value) {
if (value === null || value === undefined) {
return undefined;
}
var dte;
if(moment.isMoment(value)) {
dte = value.unix();
} else if ($.isNumeric(value)) {
dte = value;
} else if (typeof value.getTime === 'function'){
dte = value.getTime();
} else {
//When adding a new file the return date comes back like this format Nov 2, 2017 10:53:19 AM
//We need to parse it back to a moment object to parse it to the correct format
dte = moment(value, 'MMM D, YYY h:mm:ss A').unix();
}
return dte;
}
$scope.displayKey = function(cred) {
if (cred === undefined) {
return '';
}
return cred.name + (cred.credentialType === 'SSH' ? ' (SSH Key)' : ' (Username/Password)');
};
$scope.addParameter = function() {
var param = new scriptObjects.ScriptParameter();
$scope.script.parameters.push(param);
};
$scope.addSchedule = function() {
var sched = new scriptObjects.ScriptSchedule();
$scope.script.schedule.unshift(sched);
};
$scope.addScriptChain = function() {
var chain = new scriptObjects.ScriptChain();
chain.parentScript = $scope.script.id;
$scope.script.scriptChain.push(chain);
};
$scope.addEnvVar = function() {
var env = new scriptObjects.ScriptEnvironmentVariable();
$scope.script.scriptVariables.push(env);
};
$scope.addScriptEmail = function() {
$scope.model.addEmail = true;
};
$scope.removeTmpl = function() {
$scope.model.email = undefined;
$scope.model.recipients = [];
$scope.model.addEmail = false;
};
$scope.confirmTemplate = function() {
var email = new EmailTemplate($scope.model.email);
$.each($scope.model.recipients, function(key, value) {
email.recipients.push(new Account(value));
});
$scope.script.scriptEmails.push(email);
$scope.removeTmpl();
};
$scope.emailTmpl = function(email, index) {
$scope.script.scriptEmails[index] = email;
};
$scope.userUpdate = function(email, recip, index) {
email.recipients[index] = recip;
};
$scope.addRecipient = function(email) {
var user = new Account();
email.recipients.push(user);
};
$scope.moveUp = function(index, array) {
var ent1 = array[index];
var ent2 = array[index-1];
array[index] = ent2;
array[index-1] = ent1;
};
$scope.moveDown = function(index, array) {
var ent1 = array[index];
var ent2 = array[index+1];
array[index] = ent2;
array[index+1] = ent1;
};
$scope.delete = function (id, array) {
array.splice(id, 1);
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end addScriptCtrlController function
})();
@@ -0,0 +1,102 @@
<md-dialog flex="40">
<form name="userForm" ng-submit="userForm.$valid && ok()">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div>
<div layout-gt-xs="row">
<md-input-container class="md-block" flex-gt-xs>
<label>Email Address <small>(This will be their user name)</small></label>
<input ng-model="account.email" name="email" id="email" required ng-pattern="/^.+@.+\..+$/">
<div ng-messages="userForm.email.$error" ng-show="userForm.email.$invalid && submitted || userForm.email.$touched">
<div ng-message="required">Email is required</div>
<div ng-message="pattern">Email is not in correct format</div>
</div>
</md-input-container>
</div>
<div layout-gt-xs="row" layout-align="start center">
<md-input-container class="md-block" flex-gt-xs>
<label>Password</label>
<input ng-model="account.password" type="{{passwordType}}" name="password" id="password" ng-required="requirePassword">
<div ng-messages="userForm.password.$error" ng-show="userForm.password.$invalid && submitted || userForm.password.$touched">
<div ng-message="required">Password is required</div>
</div>
</md-input-container>
<md-button class="md-icon-button" style="margin-bottom: 25px;" ng-mousedown="passwordType='text'" ng-mouseup="passwordType='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
<md-input-container class="md-block" flex-gt-xs>
<label>Confirm Password</label>
<input ng-model="account.confPassword" type="{{confPasswordType}}" name="confPassword" id="confPassword"
ng-required="requirePassword" compare-to="account.password">
<div ng-messages="userForm.confPassword.$error" ng-show="userForm.confPassword.$invalid && submitted || userForm.confPassword.$touched">
<div ng-message="compareTo">Passwords do not match</div>
<div ng-message="required">Must confirm password</div>
</div>
</md-input-container>
<md-button class="md-icon-button" style="margin-bottom: 25px;" ng-mousedown="confPasswordType='text'" ng-mouseup="confPasswordType='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm>
<label>First name</label>
<input ng-model="account.firstName">
</md-input-container>
<md-input-container class="md-block" flex-gt-sm>
<label>Last Name</label>
<input ng-model="account.lastName">
</md-input-container>
</div>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm>
<label>Role</label>
<md-select ng-model="account.role" id="role" name="role" required>
<md-option value="USER">User</md-option>
<md-option value="ADMIN">Administrator</md-option>
</md-select>
<div ng-messages="userForm.role.$error" ng-show="userForm.role.$invalid && submitted || userForm.role.$touched">
<div ng-message="required">Role is required</div>
</div>
</md-input-container>
</div>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm>
<label>Effective Date</label>
<md-datepicker ng-model="account.effectiveDate"></md-datepicker>
</md-input-container>
<md-input-container class="md-block" flex-gt-sm>
<label>Expiration Date</label>
<md-datepicker ng-model="account.expirationDate"></md-datepicker>
</md-input-container>
</div>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" >OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,85 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.addUser', ['ui.router']).controller('AddUserCtrl', AddUserCtrlController);
function AddUserCtrlController($scope, modalInstance, $state, cache, $mdDialog, Account, accountProvider, portalUtils,
permissionStores, configStores, Triggers) {
$scope.header = modalInstance.header;
$scope.passwordType = 'password';
$scope.confPasswordType = 'password';
$scope.requirePassword = modalInstance.requirePassword;
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.isNew = modalInstance.account === undefined ? true : false;
$scope.account = $scope.isNew ? new Account() : modalInstance.account;
$scope.valid = false;
$scope.mCache = cache.request([new configStores.Config('userExpirationDays'),
new permissionStores.AllPermissionGroups()]).then(function(){
$scope.expirationDays = parseInt($scope.mCache.config.data.userExpirationDays);
$scope.permissionGroups = $scope.mCache.allPermissionGroups.data.values;
}).catch(function(err){
portalUtils.toast('Unable to get expiration days: ' + err.message, ['top', 'left'], 4000);
});
if ($scope.isNew) {
$scope.account.effectiveDate = new Date();
} else {
$scope.account.effectiveDate = moment($scope.account.effectiveDate);
$scope.account.expirationDate = moment($scope.account.expirationDate);
}
$scope.$watch('expirationDays', function(value){
if ($scope.isNew) {
$scope.account.expirationDate = moment().add($scope.expirationDays, 'days');
}
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
var status = $scope.isNew ? 'added': 'edited';
$scope.submitted = true;
accountProvider.addUser($scope.account).then(function(data){
$scope.loadingBlock = false;
portalUtils.toast('User ' + status + ' successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err){
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
Triggers.listen([Triggers.PERMISSIONS_ADDED, Triggers.PERMISSIONS_DELETED], function(trigger, payload){
new permissionStores.AllPermissionGroups().refresh();
});
} //end AddUserCtrlController function
})();
@@ -0,0 +1,146 @@
<md-dialog flex="60">
<form name="configForm">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>Configuration</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="General Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item>
<md-input-container flex>
<input value="File Path" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>File Path Value</label>
<input ng-model="config.filepath" ng-disabled="saving || !canEdit"/>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="Default Log Level" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Default Log Level</label>
<md-select ng-model="config.logLevel" ng-disabled="!canEdit">
<md-option ng-value="ll.id" ng-repeat="ll in logLevels">{{ll.name}}</md-option>
</md-select>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="User Expiration Days" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>User Expiration Days Value</label>
<input ng-model="config.userExpirationDays" ng-disabled="saving || !canEdit" type="number"/>
</md-input-container>
</md-list-item>
</md-list>
</md-content>
</md-tab>
<md-tab label="Database General Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item>
<md-input-container flex>
<input value="Database Host" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Database Host Value</label>
<input ng-model="config.dbHost" ng-disabled="saving || !canEdit"/>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="Database Port" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Database Port Value</label>
<input ng-model="config.dbPort" ng-disabled="saving || !canEdit" type="number"/>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="Database User Name" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Database User Name Value</label>
<input ng-model="config.dbUsername" ng-disabled="saving || !canEdit"/>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="Database Password" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<div layout="row" flex layout-align="center center">
<md-input-container flex>
<label>Database Password Value</label>
<input ng-model="config.dbPassword" ng-disabled="saving || !canEdit" type="{{dbPasswordType}}"/>
</md-input-container>
<md-button class="md-icon-button" style="margin-bottom: 25px;" ng-mousedown="dbPasswordType='text'" ng-mouseup="dbPasswordType='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
</md-list-item>
</md-list>
</md-content>
</md-tab>
<md-tab label="Database Root Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item>
<md-input-container flex>
<input value="Database Root User" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-input-container flex>
<label>Database Root User Value</label>
<input ng-model="config.dbRootUser" ng-disabled="saving || !canEdit"/>
</md-input-container>
</md-list-item>
<md-list-item>
<md-input-container flex>
<input value="Database Root Password" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<div layout="row" flex layout-align="center center">
<md-input-container flex>
<label>Database Root Password Value</label>
<input ng-model="config.dbRootPassword" ng-disabled="saving || !canEdit" type="{{dbRootPasswordType}}"/>
</md-input-container>
<md-button class="md-icon-button" style="margin-bottom: 25px;" ng-mousedown="dbRootPasswordType='text'" ng-mouseup="dbRootPasswordType='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
</md-list-item>
</md-list>
</md-content>
</md-tab>
</md-tabs>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" ng-click="ok()">Save</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,73 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.configuration', ['ui.router']).controller('ConfigurationCtrl', configurationCtrlController);
function configurationCtrlController($scope, account, $state, cache, $mdDialog, configStores, configProvider,
portalUtils, Constants, permissions) {
$scope.logLevels= [
{id:'OFF', name: 'Off'},
{id:'FATAL', name: 'Fatal'},
{id:'ERROR', name:'Error'},
{id:'WARN', name:'Warn'},
{id:'INFO', name:'Info'},
{id:'DEBUG', name:'Debug'},
{id:'TRACE', name:'Trace'},
{id:'ALL', name: 'All'}
];
$scope.saving = false;
$scope.dbPasswordType = 'password';
$scope.dbRootPasswordType = 'password';
$scope.canEdit = false;
$scope.mCache = cache.request([new configStores.Configs()]).then(function(){
$scope.config = $scope.mCache.configs.data;
});
permissions.canView({permission: Constants.Permissions.CHANGE_CONFIG}).then(function(allowed){
$scope.canEdit = allowed;
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
portalUtils.confirmBox('saveConfig', 'Save Configuration',
['Are you sure you want to save the configuration values?', 'New values will not take effect until server restart'],
false, function(value) {
if (value.confirm) {
$scope.saveConfig();
}
});
};
$scope.saveConfig = function() {
configProvider.saveConfiguration($scope.config).then(function(value){
portalUtils.toast('Configuration values saved successfully', ['top', 'left'], 2000);
new configStores.Configs().refresh();
$mdDialog.hide();
}).catch(function(err){
portalUtils.toast('Failed to save configuration: ' + err.message, ['top', 'left'], 4000);
new configStores.Configs().refresh();
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end configurationCtrlController function
})();
@@ -0,0 +1,87 @@
<md-dialog flex>
<form name="fileInfoForm" ng-submit="fileInfoForm.$valid && (moveFile ? relocate(): validate())">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-content class="md-padding" flex>
<md-list>
<md-list-item ng-if="!file.valid">
<div layout="row" layout-align="center start">
<p class="text-danger">Please enter hash value and file location to validate the file</p>
</div>
</md-list-item>
<md-list-item ng-if="file.valid && moveFile">
<div layout="row" layout-align="center start">
<p class="text-danger">Please enter new file location to move the file to</p>
</div>
</md-list-item>
<md-list-item>
<div layout="row" layout-align="center start" flex>
<md-input-container flex>
<label>File Name</label>
<input ng-model="file.fileName" ng-disabled="true" class="md-disabled-input"/>
</md-input-container>
<md-input-container flex>
<label>File Location</label>
<input ng-model="file.fileLocation" name="location" id="location" ng-required="!file.valid || moveFile" ng-disabled="file.valid && !moveFile" class="md-disabled-input"/>
<div ng-messages="fileInfoForm.location.$error" ng-show="fileInfoForm.location.$invalid && submitted || fileInfoForm.location.$touched">
<div ng-message="required">File location is required</div>
</div>
</md-input-container>
<md-input-container flex>
<label>Date Created</label>
<input ng-model="file.dateCreated" ng-disabled="true" class="md-disabled-input"/>
</md-input-container>
</div>
</md-list-item>
<md-list-item ng-if="!file.valid">
<md-input-container flex>
<label>Hash Value</label>
<input ng-model="file.newHash" name="newHash" id="newHash" class="md-disabled-input" ng-required="!file.valid"/>
<div ng-messages="fileInfoForm.newHash.$error" ng-show="fileInfoForm.newHash.$invalid && submitted || fileInfoForm.newHash.$touched">
<div ng-message="required">Hash value required</div>
</div>
</md-input-container>
</md-list-item>
<md-list-item ng-if="file.valid && !moveFile">
<md-input-container flex>
<label>MD5</label>
<input ng-model="file.md5" ng-readonly="file.valid" class="md-disabled-input"/>
</md-input-container>
</md-list-item>
<md-list-item ng-if="file.valid && !moveFile">
<md-input-container flex>
<label>SHA1</label>
<input ng-model="file.sha1" ng-readonly="file.valid" class="md-disabled-input"/>
</md-input-container>
</md-list-item>
<md-list-item ng-if="file.valid && !moveFile">
<md-input-container flex>
<label>SHA512</label>
<input ng-model="file.sha512" ng-readonly="file.valid" class="md-disabled-input"/>
</md-input-container>
</md-list-item>
</md-list>
</md-content>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="verifButton" type="submit" class="md-raised md-primary" ng-if="!file.valid">Validate</md-button>
<md-button id="verifButton" type="submit" class="md-raised md-primary" ng-if="moveFile">Move</md-button>
<md-button id="downloadButton" class="md-raised md-primary" ng-click="download()" ng-if="file.valid && !moveFile">Download</md-button>
<md-button id="okButton" class="md-raised md-warn" ng-click="ok()">Close</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,111 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.fileinfo', ['ui.router']).controller('FileInfoCtrl', fileInfoController);
function fileInfoController($scope, modalInstance, $state, cache, $mdDialog, PatchFile, portalUtils, fileProvider) {
$scope.submitted = false;
$scope.loadingBlock = false;
$scope.moveFile = modalInstance.moveFile;
$scope.header = modalInstance.header;
$scope.originalFile = modalInstance.file;
$scope.file = new PatchFile(modalInstance.file);
if (!$scope.file.valid) {
$scope.file.md5 = '';
$scope.file.sha1 = '';
$scope.file.sha512 = '';
$scope.file.fileLocation = '';
}
$scope.ok = function () {
$mdDialog.hide();
};
$scope.download = function() {
var url = '/portal/file/download.do?hashValue=' + $scope.file.sha512;
window.open(url, '');
};
$scope.relocate = function() {
portalUtils.confirmBox('relocateFile', 'Relocate File', ['Are you sure you want to relocate file:', $scope.file.fileName, 'To directory:', $scope.file.fileLocation],
false, function(value) {
if (value.confirm) {
$scope.loadingBlock = true;
fileProvider.moveFile($scope.file).then(function() {
$scope.loadingBlock = false;
portalUtils.toast('File ' + $scope.file.fileName + ' update successfully', ['top', 'left'], 2000);
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
}
});
};
$scope.validate = function() {
$scope.submitted = true;
if ($scope.file.valid) {
$mdDialog.hide();
return true;
}
$scope.error = '';
if ($scope.file.fileLocation.trim() === '') {
$scope.error = 'File location needed to validate';
return false;
}
if ($scope.file.newHash.trim() === '') {
$scope.error = 'Hash value needed';
return false;
}
if ($scope.file.newHash.trim().length === 32) {
$scope.file.md5 = $scope.file.newHash;
$scope.file.sha1 = $scope.originalFile.sha1;
$scope.file.sha512 = $scope.originalFile.sha512;
} else if ($scope.file.newHash.trim().length === 40) {
$scope.file.sha1 = $scope.file.newHash;
$scope.file.sha512 = $scope.originalFile.sha512;
$scope.file.md5 = $scope.originalFile.md5;
} else if ($scope.file.newHash.trim().length === 128) {
$scope.file.sha512 = $scope.file.newHash;
$scope.file.md5 = $scope.originalFile.md5;
$scope.file.sha512 = $scope.originalFile.sha512;
} else {
$scope.error = 'Invalid hash provided';
return false;
}
$scope.loadingBlock = true;
fileProvider.validate($scope.file).then(function(data) {
$scope.loadingBlock = false;
portalUtils.toast('File ' + $scope.file.fileName + ' update successfully', ['top', 'left'], 2000);
$scope.ok();
return true;
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
return false;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end fileInfoController function
})();
@@ -0,0 +1,22 @@
<md-dialog flex>
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<div class="modal-body-preview md-dialog-content">
<div class="previewInfoPane pad-sm">
<div ng-bind-html="trustAsHtml(content)" id="previewPopOut" name="previewPopOut"></div>
</div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<md-button id="okButton" class="md-raised md-primary" ng-click="ok()">Ok</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,41 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.filevalidate', ['ui.router']).controller('FileValidateCtrl', fileValidateController);
function fileValidateController($scope, modalInstance, $state, $mdDialog, $sce) {
$scope.header = modalInstance.header;
$scope.getContent = function() {
var content = '';
$.each(modalInstance.results, function(key, value) {
content += '<p><b>' + key + ':</b></p>';
for (var i = 0; i < value.length; i++) {
content += '<span class="text-danger">' + value[i] + '</span><br/><br/>';
}
});
$scope.content = content;
};
$scope.getContent();
$scope.trustAsHtml = function (string){
return $sce.trustAsHtml(string);
};
$scope.ok = function () {
$mdDialog.hide();
};
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end fileValidateController function
})();
@@ -0,0 +1,46 @@
<md-dialog flex="40">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>Loggers</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-card class="md-padding">
<md-list flex>
<md-list-item ng-if="canEdit">
<p><strong>All Loggers</strong></p>
<span style="width: 50px;">&nbsp;</span>
<md-select ng-model="model.alllevel" ng-change="setAllLoggers()" >
<md-option ng-value="ll.id" ng-repeat="ll in model.logLevels" >{{ll.name}}</md-option>
</md-select>
</md-list-item>
</md-list>
</md-card>
<md-card class="md-padding">
<md-tabs md-dynamic-height>
<md-tab ng-repeat="tab in tabs" layout="column" layout-fill>
<md-tab-label>{{tab.title}}</md-tab-label>
<md-tab-body>
<md-list-item ng-repeat="log in tab.loggers" flex>
<p>{{log.logger}}</p>
<span style="width: 50px;">&nbsp;</span>
<md-select ng-model="log.level" ng-disabled="!canEdit">
<md-option ng-value="ll.id" ng-repeat="ll in model.logLevels">{{ll.name}}</md-option>
</md-select>
</md-list-item>
</md-tab-body>
</md-tab>
</md-tabs>
</md-card>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" ng-click="ok()">Save</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,94 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.loggerinfo', ['ui.router']).controller('LoggerInfoCtrl', loggerInfoCtrlController);
function loggerInfoCtrlController($scope, $state, cache, $mdDialog, loggerStores, loggerProvider, portalUtils, permissions, Constants) {
$scope.saving = false;
permissions.canView({permission: Constants.Permissions.CHANGE_LOG_LEVELS}).then(function(allowed) {
$scope.canEdit = allowed;
});
$scope.tabs = [];
$scope.model = {
logLevels: [
{id:'OFF', name: 'Off'},
{id:'FATAL', name: 'Fatal'},
{id:'ERROR', name:'Error'},
{id:'WARN', name:'Warn'},
{id:'INFO', name:'Info'},
{id:'DEBUG', name:'Debug'},
{id:'TRACE', name:'Trace'},
{id:'ALL', name: 'All'}
]
};
$scope.mCache = cache.request([new loggerStores.Loggers()]).then(function(){
$scope.loggers = $scope.mCache.loggers.data.values;
var tabIndex = -1;
for (var i = 0; i < $scope.loggers.length; i++) {
if (i % 5 === 0) {
tabIndex += 1;
$scope.tabs.push({
title: 'Page' + (tabIndex + 1),
loggers: []
});
}
$scope.tabs[tabIndex].loggers.push($scope.loggers[i]);
}
});
$scope.setAllLoggers = function() {
$.each($scope.loggers, function(key, value) {
value.level = $scope.model.alllevel;
});
};
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
portalUtils.confirmBox('saveLoggers', 'Update Log Levels',
['Are you sure you want to change the logging level?'],
false, function(value) {
if (value.confirm) {
$scope.saveLoggingLevel();
}
});
};
$scope.saveLoggingLevel = function() {
loggerProvider.setLoggers($scope.loggers).then(function(value){
portalUtils.toast('Log levels set successfully', ['top', 'left'], 2000);
new loggerStores.Loggers().refresh();
$mdDialog.hide();
}).catch(function(err){
portalUtils.toast('Failed to set log levels: ' + err.message, ['top', 'left'], 4000);
new loggerStores.Loggers().refresh();
});
};
$scope.saveConfig = function() {
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end loggerInfoCtrlController function
})();
@@ -0,0 +1,68 @@
<md-dialog flex>
<form>
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div layout="row" ng-repeat="status in scriptStatus" ng-if="scriptStatus.length > 0">
<md-card flex>
<md-card-title class="md-portal-grey" flex>
<div layout="row" flex>
<strong>Run {{scriptStatus.length - $index}}</strong>
<span flex></span>
<strong>Status:&nbsp;</strong>
<strong ng-class="{'text-danger': status.exitStatus !== 0,'play-green': status.exitStatus === 0}">{{status.exitStatus !== 0 ? 'Failed' : 'Success'}}</strong>
<span flex></span>
<strong>Start: {{formatTime(status.startTime)}}</strong>
<span flex></span>
<strong>End: {{formatTime(status.endTime)}}</strong>
<span flex></span>
<md-button class="md-icon-button" ng-click="status.expanded = !status.expanded">
<md-icon>{{ status.expanded ? 'expand_less' : 'expand_more' }}</md-icon>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">{{status.expanded ? 'Collapse' : 'Expand'}}</md-tooltip>
</md-button>
</div>
</md-card-title>
<pre ng-if="status.expanded">{{status.results}}</pre>
<md-card-content class="md-padding" ng-if="status.expanded && status.resourceFiles.length > 0">
<p><strong>Files available for download</strong></p>
<md-list>
<md-list-item>
<b>File Name</b>
</md-list-item>
<md-list-item ng-repeat="file in status.resourceFiles">
<div layout="row" layout-align="start center" flex>
<p>{{file.fileName}}</p>
<span flex></span>
<div layout="row" layout-align="end center">
<md-button class="md-icon-button" ng-click="download(file)">
<md-icon class="md-16">file_download</md-icon>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Download File</md-tooltip>
</md-button>
<md-button class="md-icon-button" ng-click="delete(file)" has-permission="{{Constants.Permissions.DELETE_FILE}}">
<md-icon class="md-16">delete</md-icon>
<md-tooltip md-delay="500" class="mediaTileToolTip" md-direction="left">Delete File</md-tooltip>
</md-button>
</div>
</div>
</md-list-item>
</md-list>
</md-card-content>
</md-card>
</div>
<div layout="row" ng-if="scriptStatus.length === 0">
<strong class="text-warn">No script job status found for select script job</strong>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,84 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.viewScriptStatus', ['ui.router']).controller('ScriptStatusCtrl', ScriptStatusCtrl);
function ScriptStatusCtrl($scope, modalInstance, cache, $mdDialog, scriptObjects, scriptProvider, fileProvider, portalUtils,
Triggers, Constants) {
$scope.header = modalInstance.header;
$scope.scriptStatus = [];
$scope.Constants = Constants;
$scope.confirmQuestionBox = true;
$scope.init = function() {
scriptProvider.getScriptStatus(modalInstance.jobId).then(function(data){
$scope.scriptStatus = [];
for (var i = 0; i < data.length; i++) {
$scope.scriptStatus.push(new scriptObjects.ScriptStatus(data[i]));
}
});
};
$scope.init();
$scope.formatTime = function(value) {
if (value === null || value === undefined) {
return 'None';
}
return moment(value).format('MM/DD/Y HH:mm:ss');
};
$scope.delete = function(entity) {
if ($scope.confirmQuestionBox) {
portalUtils.confirmBox('deleteFile', 'Delete File', ['Are you sure you want to delete the file', entity.fileName],
true, function(value) {
if (value.confirm) {
$scope.confirmQuestionBox = !value.checkbox;
$scope.deleteFile(entity);
}
});
} else {
$scope.deleteFile(entity);
}
};
$scope.deleteFile = function(entity) {
fileProvider.deleteFile(entity).then(function() {
portalUtils.toast('File deleted successfully', ['top', 'left'], 2000);
}).catch(function(err){
portalUtils.toast('File failed to delete: ' + err.message, ['top', 'left'], 4000);
});
};
$scope.ok = function () {
};
$scope.download = function(row) {
var url = '/portal/file/download.do?id=' + row.id;
window.open(url, '');
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
Triggers.listen([Triggers.FILE_DELETED], function(trigger, payload){
$scope.init();
});
} //end addEnvVarCtrlController function
})();
@@ -0,0 +1,26 @@
<md-dialog flex="40">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>AES Seed</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-card class="md-padding">
<md-input-container flex>
<label>Seed Value</label>
<input ng-model="model.seed" ng-disabled="saving || !canEdit"/>
</md-input-container>
</md-list-item>
</md-card>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" ng-click="ok()">Save</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,56 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.seedinfo', ['ui.router']).controller('SeedInfoCtrl', seedInfoCtrlController);
function seedInfoCtrlController($scope, $state, cache, $mdDialog, systemProvider, portalUtils, permissions, Constants) {
$scope.saving = false;
permissions.canView({permission: Constants.Permissions.UPDATE_SEED_VALUE}).then(function(allowed) {
$scope.canEdit = allowed;
});
$scope.model = {};
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
portalUtils.confirmBox('updateSeed', 'Update AES Seed',
['Are you sure you want to update the AES Seed',
'This will go through and update all the saved encrypted values',
'and cannot be undone once performed'],
false, function(value) {
if (value.confirm) {
$scope.updateSeed();
}
});
};
$scope.updateSeed = function() {
systemProvider.updateSeed($scope.model.seed).then(function(){
portalUtils.toast('Seed updated successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}, function(err){
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
} //end SeedInfoCtrlController function
})();
@@ -0,0 +1,20 @@
<md-dialog>
<form>
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>Alert!</span>
<span flex></span>
</div>
</md-toolbar>
<md-dialog-content layout-padding flex>
<div layout="row">
<div ng-bind-html="message"></div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-warn" ng-if="btnCnlText !== undefined" ng-click="onCancel()">{{btnCnlText}}</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="onOkay()">{{btnText}}</md-button>
</md-dialog-actions>
</form>
</md-dialog>
@@ -0,0 +1,16 @@
(function () {
'use strict';
angular.module('portal.common.partials.sessionEnd', ['ui.router'])
.controller('SessionEndCtrl', SessionEndCtrlController);
function SessionEndCtrlController($scope, modalInstance, $state, cache) {
$scope.onOkay = modalInstance.onOkay;
$scope.message = modalInstance.message;
$scope.btnText = modalInstance.btnText;
$scope.btnCnlText = modalInstance.btnCnlText;
$scope.onCancel = modalInstance.onCancel;
} //end SessionEndCtrlController function
})();
@@ -0,0 +1,93 @@
<md-dialog flex="40">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>SMTP Configuration</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="General Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item ng-repeat="conf in smtpConfig | limitTo: 5">
<div layout="row" layout-align="center start" flex>
<md-input-container>
<input ng-model="conf.displayValue" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-switch flex ng-model="conf.value" ng-if="conf.type === 'boolean'" class="md-primary" ng-disabled="!canEdit">{{conf.value ? 'Yes' : 'No'}}</md-switch>
<div layout="row" layout-align="start center" flex ng-if="conf.type !== 'boolean'">
<md-input-container flex>
<input ng-model="conf.value" ng-disabled="!canEdit" type="{{conf.type}}" />
</md-input-container>
<md-button class="md-icon-button" ng-if="conf.meta === 'password'" style="margin-bottom: 25px;" ng-mousedown="conf.type='text'" ng-mouseup="conf.type='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
</div>
</md-list-item>
</md-list>
</md-content>
</md-tab>
<md-tab label="Start TLS Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item ng-repeat="conf in smtpConfig | limitTo: 3:5">
<div layout="row" layout-align="center start" flex>
<md-input-container>
<input ng-model="conf.displayValue" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-switch flex ng-model="conf.value" ng-if="conf.type === 'boolean'" class="md-primary" ng-disabled="!canEdit">{{conf.value ? 'Yes' : 'No'}}</md-switch>
<div layout="row" layout-align="start center" flex ng-if="conf.type !== 'boolean'">
<md-input-container flex>
<input ng-model="conf.value" ng-disabled="!canEdit" type="{{conf.type}}" />
</md-input-container>
<md-button class="md-icon-button" ng-if="conf.meta === 'password'" style="margin-bottom: 25px;" ng-mousedown="conf.type='text'" ng-mouseup="conf.type='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
</div>
</md-list-item>
</md-list>
</md-content>
</md-tab>
<md-tab label="Auth Configuration">
<md-content class="md-padding" flex>
<md-list>
<md-list-item ng-repeat="conf in smtpConfig | limitTo: 4:8">
<div layout="row" layout-align="center start" flex>
<md-input-container>
<input ng-model="conf.displayValue" ng-disabled="true" style="color: rgba(0,0,0,1) !important; background: none !important;"/>
</md-input-container>
<span flex="5"></span>
<md-switch flex ng-model="conf.value" ng-if="conf.type === 'boolean'" class="md-primary" ng-disabled="!canEdit">{{conf.value ? 'Yes' : 'No'}}</md-switch>
<div layout="row" layout-align="start center" flex ng-if="conf.type !== 'boolean'">
<md-input-container flex>
<input ng-model="conf.value" ng-disabled="!canEdit" type="{{conf.type}}" />
</md-input-container>
<md-button class="md-icon-button" ng-if="conf.meta === 'password'" style="margin-bottom: 25px;" ng-mousedown="conf.type='text'" ng-mouseup="conf.type='password'">
<md-icon>remove_red_eye</md-icon>
<md-tooltip>View password</md-tooltip>
</md-button>
</div>
</div>
</md-list-item>
</md-list>
</md-content>
</md-tab>
</md-tabs>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger">{{error}}</div>
<md-button id="okButton" type="submit" class="md-raised md-primary" ng-click="ok()">Save</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,140 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.smtpinfo', ['ui.router']).controller('SMTPInfoCtrl', smtpInfoCtrlController);
function smtpInfoCtrlController($scope, $state, cache, $mdDialog, systemProvider, systemStores,
portalUtils, permissions, Constants, Triggers) {
$scope.saving = false;
permissions.canView({permission: Constants.Permissions.EDIT_SMTP_CONFIG}).then(function(allowed){
$scope.canEdit = allowed;
});
$scope.smtpConfig = [
{
name: 'smtp.enabled',
displayValue: 'SMTP Enabled',
value: false,
type: 'boolean'
},{
name: 'mail.transport.protocol',
displayValue: 'Transport Protocol',
value: 'smtp',
type: 'text'
},{
name: 'mail.smtp.host',
displayValue: 'SMTP Server Url',
value: '',
type: 'text'
},{
name: 'mail.smtp.port',
displayValue: 'SMTP Server Port',
value: 0,
type: 'number'
},{
name: 'mail.debug',
displayValue: 'Enable Mail Debug Logging',
value: false,
type: 'boolean'
},{
name: 'mail.smtp.starttls.enable',
displayValue: 'Enable Start TLS',
value: false,
type: 'boolean'
},{
name: 'mail.smtp.starttls.required',
displayValue: 'Require Start TLS',
value: false,
type: 'boolean'
},{
name: 'mail.smtp.ssl.trust',
displayValue: 'SSL Trust Certificate',
value: '*',
type: 'text'
},{
name: 'mail.smtp.auth',
displayValue: 'Require Authentication',
value: false,
type: 'boolean'
},{
name: 'smtp.from.user',
displayValue: 'From User',
value: '',
type: 'text'
},{
name: 'smtp.username',
displayValue: 'SMTP Username',
value: '',
type: 'text'
},{
name: 'smtp.password',
displayValue: 'SMTP Password',
value: '',
type: 'password',
meta: 'password'
},
];
$scope.mCache = cache.request([new systemStores.SMTPConfig()]).then(function(){
var conf = $scope.mCache.smtpConfig.data.values;
$.each($scope.smtpConfig, function(key, value) {
$.each(conf, function(key2, value2) {
if (value.name === value2.name) {
if (value.type === 'number') {
value.value = parseInt(value2.value);
} else if (value.type === 'boolean') {
value.value = value2.value === 'true' || value2.value === true;
} else {
value.value = value2.value;
}
return;
}
});
});
});
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
portalUtils.confirmBox('saveSmtpConfig', 'Update SMTP Configuration',
['Are you sure you want to update the smtp configuration?'],
false, function(value) {
if (value.confirm) {
$scope.saveSMTPConf();
}
});
};
$scope.saveSMTPConf = function() {
systemProvider.updateSmtpConfig($scope.smtpConfig).then(function() {
$mdDialog.hide();
}).catch(function(err) {
$scope.error = err.message;
portalUtils.toast('Failed to save configuration: ' + err.message, ['top', 'left'], 4000);
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
Triggers.listen([Triggers.SMTP_CONFIG_UPDATED], function(trigger, payload) {
new systemStores.SMTPConfig().refresh();
});
} //end smtpInfoCtrlController function
})();
@@ -0,0 +1,25 @@
<md-dialog>
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{confirmTitle}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<div layout="column" class="md-padding">
<ng-repeat ng-repeat="message in confirmMessage">
<p>{{message}}</p>
</ng-repeat>
<div layout="row">
<md-checkbox class="md-primary" ng-if="showConfirmMessage" ng-model="data.checkbox">Do not show this message again</md-checkbox>
</div>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<md-button id="{{btnId}}-confirm" class="md-raised md-primary" ng-click="confirm()">Yes</md-button>
<md-button id="{{btnId}}-cancel" class="md-raised md-warn" ng-click="cancel()">No</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,39 @@
<md-dialog flex="15">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{title}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<div layout="column" class="md-padding" flex>
<p class="text-danger">{{message}}</p>
<md-input-container flex>
<label style="padding-left: 35px;">Purge Start Date</label>
<input mdc-datetime-picker="" date="true" time="false" type="text" id="startdatetime"
show-todays-date="" minutes="true" min-date="date" show-icon="true" format='MMM D, YYYY'
ng-model="model.purgeStartDate" class=" dtp-no-msclear dtp-input">
</md-input-container>
<md-input-container flex>
<label style="padding-left: 35px;">Purge End Date</label>
<input mdc-datetime-picker="" date="true" time="false" type="text" id="startdatetime"
show-todays-date="" minutes="true" min-date="date" show-icon="true" format='MMM D, YYYY'
ng-model="model.purgeEndDate" class=" dtp-no-msclear dtp-input">
</md-input-container>
</div>
</md-dialog-content>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
<md-dialog-actions layout="column" class="modal-footer" flex>
<div class="text-danger">{{error}}</div>
<div layout="row" layout-align="end center">
<md-button id="purge-confirm" class="md-raised md-primary" ng-click="confirm()">Ok</md-button>
<md-button id="purge-cancel" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</div>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,31 @@
<md-dialog flex="50">
<md-toolbar>
<div class="md-toolbar-tools md-portal">
<span>{{header}} to {{currentDir}}</span>
<span flex></span>
<md-button class="md-icon-button" ng-click="cancel()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content flex>
<div layout="row" flex="100" class="md-dialog-content" id="fileInputDiv">
<repo-file-input id="fileInput" name="file" ng-model="uploadFile" accepts="false" flex></repo-file-input>
</div>
<div layout="row" flex="100" class="md-dialog-content">
<md-input-container flex>
<label>Hash Value</label>
<input type="text" id="fileName" ng-model="model.hashValue" required>
</md-input-container>
</div>
<div ng-show="loadingBlock" class="loadingFade"></div>
<div class="loadingModal" ng-show="loadingBlock">
<md-progress-circular md-mode="indeterminate" md-diameter="80" class="md-hue-2"></md-progress-circular>
</div>
</md-dialog-content>
<md-dialog-actions layout="row" class="modal-footer">
<div class="text-danger text-center">{{error}}</div>
<md-button id="okButton" class="md-raised md-primary" ng-click="ok()" ng-disabled="!valid">OK</md-button>
<md-button id="cancelButton" class="md-raised md-warn" ng-click="cancel()">Cancel</md-button>
</md-dialog-actions>
</md-dialog>
@@ -0,0 +1,73 @@
(function () {
'use strict';
/**
* MODULE DESCRIPTION:
*
* TODO: Write description here.
*/
angular.module('portal.common.partials.uploadpatchfile', ['ui.router'])
.controller('UploadPatchFileCtrl', UploadPatchFileCtrlController);
function UploadPatchFileCtrlController($scope, modalInstance, $state, cache, $mdDialog, fileProvider, UploadFile, portalUtils) {
$scope.header = modalInstance.header;
$scope.currentDir = modalInstance.currentDir;
$scope.uploadFile = undefined;
$scope.loadingBlock = false;
$scope.model = { };
$scope.valid = false;
$scope.$watch('model', function(){
if ($scope.model.hashValue === undefined || $scope.model.hashValue.trim() === '') {
$scope.valid = false;
return;
}
if ($scope.uploadFile === undefined) {
$scope.valid = false;
return;
}
$scope.valid = true;
}, true);
/**
* OK button handler
* @returns {undefined}
*/
$scope.ok = function () {
$scope.loadingBlock = true;
fileProvider.uploadFile([new UploadFile().init($scope.uploadFile)], $scope.model.hashValue, $scope.currentDir).then(function(data) {
$scope.loadingBlock = false;
portalUtils.toast('File uploaded successfully', ['top', 'left'], 2000);
$mdDialog.hide();
}).catch(function(err) {
$scope.loadingBlock = false;
$scope.error = err.message;
});
};
/**
* Cancel button handler.
* @returns {undefined}
*/
$scope.cancel = function () {
//Dismiss the modal
$mdDialog.cancel();
};
$scope.$on('$destroy', function () {
if ($scope.mCache !== undefined) {
$scope.mCache.unlisten();
}
});
} //end UploadPatchFileCtrlController function
})();
@@ -0,0 +1,125 @@
(function () {
'use strict';
/**
* DESCRIPTION: Deferred authorization handler.
*/
angular.module('portal.common.services.authorize', ['ui.router'])
.service('authorize', authorizeService);
function authorizeService($state, $q, cache, accountStores) {
/**
* Defines the different types of auth checkers.
* @type type
*/
var authHandlers = {
account: function (args) {
var deferred = $q.defer();
var mCache = cache.request([new accountStores.Account()]).once(function () {
var authorized = false;
for (var i = 0; i < args.length; i++) {
if (mCache.account.data.authoritiesMap.containsKey(args[i])) {
authorized = true;
break;
}
}
deferred.resolve(authorized);
}).catch(function () {
deferred.reject();
});
return deferred.promise;
},
permission: function (args) {
var deferred = $q.defer();
var mCache = cache.request([new accountStores.Account()]).once(function () {
var acct = mCache.account.data;
if (!acct.enabled) {
deferred.resolve(false);
return;
}
var authorized = false;
for (var i = 0; i < args.length; i++) {
if (acct.hasPermission(args[i])) {
authorized = true;
break;
}
}
deferred.resolve(authorized);
}).catch(function (err) {
deferred.reject();
});
return deferred.promise;
}
};
/**
* Chains deferrals so we don't have to nest them.
*
* Yes, this is kind of complicated, its async recursion. Tried to help with
* comments but only so much you can do.
*
* @param {type} authorities
* @param {type} keys
* @param {type} i
* @param {type} isValid
* @returns {$q@call;defer.promise}
*/
function validate(authorities, keys, i, isValid) {
var deferred = $q.defer();
//If still within bounds of authorities array
//call the auth handler and if we are still valid
//No point in continuing if we are no longer valid.
if (i < keys.length && isValid) {
authHandlers[keys[i]](authorities[keys[i]]).then(function (valid) {
//When the auth handler returns, chain up the next one
//by calling validate again.
//Its important to combine the valid status as we go.
return validate(authorities, keys, i + 1, isValid && valid);
}).then(function (valid) {
//calling deferred in the then allows us to close our chains.
deferred.resolve(valid);
}).catch(function(){
deferred.reject();
});
} else {
//This is the last link in the chain, if we don't call resolve
//we won't start linking the rest of the chains.
deferred.resolve(isValid);
}
return deferred.promise;
}
return {
/**
* Deferred validation routine for the ui-router resolve
* functionality. UI-router listens for the promise to be resolved
* before movingn to the next state.
*
* This avoids us having to do awkard redirects while we check
* server for status.
*
* @param {type} args
* @returns {$q@call;defer.promise}
*/
validate: function (args) {
var deferred = $q.defer();
if (angular.isObject(args.authorities)) {
var keys = Object.keys(args.authorities);
validate(args.authorities, keys, 0, true).then(function (isValid) {
if (!isValid) {
$state.go(args.redirect);
}
deferred.resolve();
}).catch(function () {
$state.go(args.redirect);
});
} else {
deferred.resolve();
}
return deferred.promise;
}
};
} //end authorizeService function
})();
@@ -0,0 +1,200 @@
(function () {
'use strict';
/**
* DESCRIPTION:
*
* Special map object for easy access to both an object map and an array.
*
* This object mimics maps as defined by the Java map interface.
*/
angular.module('portal.common.services.map', ['ui.router'])
.factory('Map', mapService);
function mapService() {
/**
* Defines a map object that allows storage of data as array and object.
* @param {type} accessor The value used on elements for the key, e.g. element.id => "id"
* @returns {map_L35.mapService.Map}
*/
function Map(accessor, groupKeys) {
var map = this;
/** Array Storage. */
map.values = [];
/** Object Storage. */
map.object = {};
/** Group Storage. */
map.groups = {};
/** Group keys. */
map.groupKeys = [];
if (angular.isArray(groupKeys)) {
map.groupKeys = groupKeys.slice();
} else if (angular.isDefined(groupKeys)) {
map.groupKeys.push(groupKeys);
}
//Initialize Groups
for (var i = 0; i < map.groupKeys.length; i++) {
map.groups[map.groupKeys[i]] = {};
}
/**
* defines the part of the element that comprises the key.
* May be undefined, not guaranteed.
*/
map.accessor = accessor;
/**
* @returns {Boolean} True if emtpy.
*/
map.isEmpty = function () {
return map.values.length === 0;
};
/**
* Determins if an item is stored inside based on its key.
* @param {type} key
* @returns {Boolean} True if contained.
*/
map.containsKey = function (key) {
return angular.isDefined(map.object[key]);
};
/**
* Searches for element, via loop.
* @param {type} value
* @returns {Boolean} True if element found.
*/
map.containsValue = function (value) {
for (var i = 0; i < map.values.length; i++) {
if (map.values[i] === value) {
return true;
}
}
return false;
};
/**
* @param {type} key
* @returns {type} element found by key.
*/
map.get = function (key) {
return map.object[key];
};
/**
* Inserts element into both array and object storage.
* @param {type} key
* @param {type} value
*/
map.put = function (key, value) {
//Remove elements.
map.removeByKey(key);
//Insert.
map.values.push(value);
map.object[key] = value;
//Group
for (var i = 0; i < map.groupKeys.length; i++) {
var groupKey = map.groupKeys[i];
var group = value[groupKey];
if (!angular.isDefined(map.groups[groupKey][group])) {
map.groups[groupKey][group] = new Map(map.accessor);
}
map.groups[groupKey][group].put(key, value);
}
return value;
};
/**
* Allows access to a group map.
* Always returns a valid map, just may be empty.
* @param {type} group
* @returns {map_L35.mapService.Map}
*/
map.getGroup = function (groupKey, group) {
if (angular.isDefined(map.groups[groupKey][group])) {
return map.groups[groupKey][group];
}
return new Map();
};
/**
* Removes an element from both storage interfaces.
* @param {type} key
* @returns {Boolean} T/F if removed or not.
*/
map.removeByKey = function (key) {
if (!map.containsKey(key)) {
return false;
}
var value = map.object[key];
//Remove from Array.
for (var i = 0; i < map.values.length; i++) {
if (map.values[i] === value) {
map.values.splice(i, 1);
break;
}
}
//Remove from object.
delete map.object[key];
//Remove from groups.
for (var j = 0; j < map.groupKeys.length; j++) {
var groupKey = map.groupKeys[j];
var group = value[groupKey];
if (angular.isDefined(map.groups[groupKey][group])) {
map.groups[groupKey][group].removeByKey(key);
}
}
return true;
};
/**
* Empties the storage objects.
*/
map.clear = function () {
map.object = {};
map.values = [];
};
map.init = function (data, Constructor, accessor) {
map.clear();
map.accessor = accessor;
if (angular.isArray(data)) {
for (var i = 0; i < data.length; i++) {
var obj = new Constructor(data[i]);
map.put(obj[accessor], obj);
}
}
};
Object.defineProperties(map, {
/**
* Returns the keys from the object.
*/
keySet: {
get: function () {
return Object.keys(map.object);
}
},
length: {
get: function () {
return map.values.length;
}
}
});
}
Map.create = function (data, Constructor, accessor, groupKeys) {
var map = new Map(accessor, groupKeys);
map.init(data, Constructor, accessor);
return map;
};
return Map;
} //end mapService function
})();
+133
View File
@@ -0,0 +1,133 @@
(function () {
'use strict';
/**
* DESCRIPTION: Box contains data and status for the store and cache.
*/
angular.module('portal.common.services.model.cache')
.factory('Box', boxService);
function boxService(portalUtils, Listener, Triggers, $q) {
/**
* Box obejct to enacupsulate the data so it can be watched.
* @returns {undefined}
*/
var Box = portalUtils.inherit(function (args) {
var box = this;
Listener.call(box);
/**
* Container for data.
*/
box.data = undefined;
/**
* Container for error.
*/
box.errorData = undefined;
/**
* Status of the data request.
*/
box.status = Box.Status.NEW;
/** Function to handle client side data processing. */
box.processGui = args.processGui;
/** Function to handle parallel processing. */
box.processParallel = args.processParallel;
/** Function for deferred processing, expects $q promise. */
box.processDeferred = args.processDeferred;
if (angular.isDefined(args.triggers)) {
Triggers.listen(args.triggers, function(trigger, payload) {
portalUtils.call(args.processTrigger, trigger, payload, box);
});
}
box.init = function() {
if (box.status === Box.Status.NEW) {
box.status = Box.Status.PENDING;
if (angular.isFunction(args.source)) {
args.source(args.params).then(function (payload) {
box.update(payload);
}).catch(function(payload){
box.onError(payload);
});
} else {
console.error('Store source function was not a function.');
}
}
return box.listen();
};
box.refresh = function () {
var deferred = $q.defer();
if (box.status !== Box.Status.PENDING &&
angular.isFunction(args.source)) {
box.status = Box.Status.PENDING;
args.source(args.params).then(function (payload) {
if (angular.isFunction(box.processDeferred)) {
box.update(payload).then(deferred.resolve);
} else {
box.update(payload);
deferred.resolve();
}
});
} else {
deferred.resolve();
}
return deferred.promise;
};
box.update = function (_data) {
box.status = Box.Status.DONE;
var data = _data;
if (angular.isFunction(box.processParallel)) {
data = box.processParallel(data);
}
if (angular.isFunction(box.processGui)) {
data = box.processGui(data);
}
if (angular.isFunction(box.processDeferred)) {
return box.processDeferred(data).then(function(_data){
return update(_data);
});
} else {
return update(data);
}
};
box.onError = function(_data) {
box.status = Box.Status.ERROR;
box.errorData = _data;
box.notifyError();
};
function update(data) {
box.data = data;
box.notify();
}
box.clear = function () {
box.data = undefined;
box.status = Box.Status.new;
box.notify();
};
box.isDone = function () {
return box.status === Box.Status.DONE;
};
}, Listener);
/**
* Status enum
*/
Box.Status = {
NEW: 0,
PENDING: 1,
DONE: 2,
ERROR: 3
};
return Box;
} //end boxService function
})();
+192
View File
@@ -0,0 +1,192 @@
(function () {
'use strict';
/**
* DESCRIPTION: Provides entry to the cache service.
*/
angular.module('portal.common.services.model.cache', ['ui.router'])
.service('cache', cacheService);
function cacheService($cacheFactory, portalUtils, Store, Request, $rootScope, Listener) {
/**
* $cacheFactory instances for storing all cache data. Shared between tabs.
*
* This may be better placed in app.js
*
* Why are we collecting rootscopes? because when data changes on the
* shared cache we need to notify everyone via $digest. This is
* done in the Listener.digest function.
*
* @type @call;$cacheFactory
*/
var caches = {};
var scopes = [];
if (angular.isObject(window.opener) && angular.isObject(window.opener.cacheService)) {
caches = window.opener.cacheService.caches;
scopes = window.opener.cacheService.rootScopes;
scopes.push($rootScope);
} else {
caches.data = $cacheFactory('dataCache');
caches.http = $cacheFactory('httpCache');
scopes = [$rootScope];
window.cacheService = {caches: caches, rootScopes: scopes};
}
Store.registerCache(caches.data);
Request.registerCache(caches.http);
Listener.registerScopes(scopes);
/**
* Mini Cache Object.
* Provides an isolated cache with only data points
* that were requested.
* @param _stores
* @returns {undefined}
*/
function MiniCache(_stores) {
var miniCache = this;
/** Stores in this cache. */
var stores = _stores;
/** Callbacks registered on then(...) */
var dataCallBack = null;
var errorCallback = null;
/** Parent cache in chained caches. */
miniCache.parent = null;
/** Allows for a do once and unsubscribe. */
var doOnce = false;
/**
* Allows tracking of first round of notifications
* to avoid multiple notify calls when all data sets are
* ready.
*/
var storesReady = {};
//Activate (Listen) to the stores in this minicache.
for (var i = 0; i < stores.length; i++) {
var store = stores[i];
if (store instanceof Store) {
storesReady[store.id] = false;
store.init().then(notify(store)).catch(error(store));
miniCache[store.id] = store.getBox();
}
}
/**
* Promise Accessor
* @param {type} callback
* @returns {cache_L35.cacheService.MiniCache}
*/
miniCache.then = function (callback, errorCallback) {
dataCallBack = callback;
miniCache.catch(errorCallback);
return this;
};
miniCache.catch = function (callback) {
errorCallback = callback;
return this;
};
/**
* Promise Accessor
* @param {type} callback
* @returns {undefined}
*/
miniCache.once = function (callback) {
miniCache.then(callback);
doOnce = true;
return this;
};
/**
* Notifies callback in .then, only called when all are ready.
* @returns {undefined}
*/
function notify(store) {
var _store = store;
//returned function is what is called by the store,
//the wrapping allows us to keep track of which stores have
//triggered once.
return function () {
storesReady[_store.id] = true;
//Verify all stores are ready before notifiying listeners.
for (var j = 0; j < stores.length; j++) {
var store = stores[j];
if (!storesReady[store.id] || stores[j].isReady() === false) {
return;
}
}
if (doOnce) {
miniCache.unlisten();
}
miniCache.merge(portalUtils.call(dataCallBack));
};
}
function error(store) {
var _store = store;
return function () {
portalUtils.call(errorCallback, _store);
};
}
miniCache.merge = function (mCache) {
if (mCache instanceof MiniCache) {
mCache.parent = miniCache;
if (miniCache.parent === null) {
//Copy boxes.
var mCacheStores = mCache.getStores();
for (var i = 0; i < mCacheStores.length; i++) {
miniCache[mCacheStores[i].id] = mCache[mCacheStores[i].id];
}
} else {
miniCache.parent.merge(mCache);
}
}
};
miniCache.getStores = function () {
return stores;
};
/**
* Allows you to purge listeners.
* @returns {undefined}
*/
miniCache.unlisten = function () {
for (var i = 0; i < stores.length; i++) {
stores[i].unlisten();
}
};
}
/*
* Public Methods
*/
return {
/**
* Allows data to be requested.
* @param {type} stores
* @returns {MiniCache} Mini cache with requested data
*/
request: function (stores) {
var storesArray = [];
//Arrayify the data points.
if (angular.isArray(stores)) {
storesArray = stores.slice();
} else {
storesArray.push(stores);
}
return new MiniCache(storesArray);
},
/**
* Purges the cache.
*/
flush: function () {
caches.data.removeAll();
caches.http.removeAll();
}
};
} //end cacheService function
})();
@@ -0,0 +1,145 @@
(function () {
'use strict';
/**
* DESCRIPTION:
*/
angular.module('portal.common.services.model.cache')
.service('Listener', listenerService);
function listenerService(Map, $q, debounce, $rootScope) {
var Listener = function () {
var li = this;
var successMap = new Map();
var errorMap = new Map();
var subscriberId = 0;
var notified = false;
var errored = false;
var errorArgs = [];
var successArgs = [];
li.Listen = function () {
var pr = this;
pr.successIds = [];
pr.errorIds = [];
pr.then = function (success, error) {
if (angular.isFunction(success)) {
pr.successIds.push(subscriberId);
successMap.put(subscriberId, success);
subscriberId++;
}
pr.catch(error);
if (notified) {
call(success, successArgs);
}
return pr;
};
pr.catch = function (error) {
if (angular.isFunction(error)) {
pr.errorIds.push(subscriberId);
errorMap.put(subscriberId, error);
subscriberId++;
}
if (errored) {
call(error, errorArgs);
}
return pr;
};
pr.unlisten = function () {
var i = 0;
for (i = 0; i < pr.successIds.length; i++) {
successMap.removeByKey(pr.successIds[i]);
}
for (i = 0; i < pr.errorIds.length; i++) {
errorMap.removeByKey(pr.errorIds[i]);
}
};
};
li.listen = function () {
return new li.Listen();
};
li.notify = function (timeout) {
notified = true;
successArgs = arguments;
return callMap(successMap, successArgs, timeout);
};
li.notifyError = function () {
errored = true;
errorArgs = arguments;
return callMap(errorMap, arguments);
};
function callMap(map, args, timeout) {
var promises = [];
for (var i = 0; i < map.length; i++) {
promises.push(call(map.values[i], args, timeout));
}
return $q.all(promises);
}
function call(callee, args, timeout) {
var deferred = $q.defer();
if (angular.isFunction(callee)) {
window.setTimeout(function () {
callee.apply(li, args);
Listener.digest();
deferred.resolve();
}, timeout);
}
return deferred.promise;
}
};
var scopes;
Listener.registerScopes = function(_scopes) {
scopes = _scopes;
};
/**
* This allows us to only digest once we settle down.
* This debounce waits 100ms if it doesn't get another
* request to digest it will digest. Every request
* resets the timer to 100ms. This prevents us from
* hammering the CPU on load.
*
* Note: I have read the many many things on the internet that say
* we shouldn't do this. That we are breaking $angular convention, and I
* am ok with that. portal is not a public facing website.
*
* We are doing this because $timeout takes about 500ms to a 1s to make
* an async call. setTimeout is significantly faster. But that takes us
* outside of a digest cycle which means angular watches won't be re-evaluated.
* We must call $digest to get them to update.
*
* Conventionally you should call $scope.$apply, but that results in the same
* delays as $setTimout.
*
* Alternatively we could make this synchronous but doing so prohibits UI
* drawing/interaction which is not conducive to a good UI.
*
*/
Listener.digest = debounce(function () {
console.log('DIGESTING');
for (var i = 0; i < scopes.length; i++) {
try {
scopes[i].$digest();
} catch (err){
console.log('WARN: Digest already in progerss');
}
}
}, 100);
return Listener;
} //end listenerService function
})();
@@ -0,0 +1,91 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an Account object, which defines the person who has
* authenticated with the server.
*/
angular.module('portal.common.services.model.cache')
.service('Account', accountService);
function accountService(Map, Constants) {
function Account(data) {
var account = this;
account.id = null;
account.authoritiesMap = new Map('id');
account.username = '';
account.password = '';
account.lastName = '';
account.firstName = '';
account.auId = null;
account.email = '';
account.role = '';
account.expirationDate = '';
account.effectiveDate = '';
account.stompTopics = [];
account.permissions = {};
account.enabled = false;
account.fromData = function (data) {
account.id = data.id;
account.authoritiesMap = new Map('id');
account.username = data.username;
account.password = null;
account.lastName = data.lastName;
account.firstName = data.firstName;
account.auId = data.auId;
account.email = data.email;
account.role = data.role;
account.expirationDate = data.expirationDate;
account.effectiveDate = data.effectiveDate;
account.stompTopics = data.stompTopics;
account.permissions = data.permissions;
account.enabled = data.enabled;
if (angular.isArray(data.authorities)) {
for (var i = 0; i < data.authorities.length; i++) {
var authority = Account.Authorities.getTypeFromString(data.authorities[i]);
account.authoritiesMap.put(authority.id, authority);
}
}
};
if (angular.isDefined(data)) {
account.fromData(data);
}
account.hasPermission = function(key) {
return account.authoritiesMap.containsKey(key);
};
}
/**
* Object defining a account authority
* @param {type} id
* @param {type} name
* @returns {Account.Authority}
*/
Account.Authority = function (id, name) {
var userType = this;
userType.id = id;
userType.name = name;
};
Account.Authority.prototype.toString = function () {
return this.id;
};
/**
* Defines the statically typed account Authority as an enum (of sorts)
*/
Account.Authorities = {
getTypeFromString: function (typeAsString) {
return Account.Authorities[typeAsString];
}
};
$.each(Constants.Permissions, function(key, value) {
Account.Authorities[key] = new Account.Authority(key, value.replace(/_/g, ' '));
});
return Account;
} //end accountService function
})();
@@ -0,0 +1,40 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an Account object, which defines the person who has
* authenticated with the server.
*/
angular.module('portal.common.services.model.cache')
.service('ApplicationLog', appLogService);
function appLogService(Map) {
function ApplicationLog(data) {
var appLog = this;
appLog.id = '';
appLog.eventName = '';
appLog.event = '';
appLog.severity = '';
appLog.ipAddress = '';
appLog.timestamp = '';
appLog.loggedBy = '';
appLog.fromData = function (data) {
appLog.id = data.id;
appLog.loggedBy = data.loggedBy;
appLog.eventName = data.eventName;
appLog.event = data.event;
appLog.severity = data.severity;
appLog.ipAddress = data.ipAddress;
appLog.timestamp = moment(data.timestamp);
};
if (angular.isDefined(data)) {
appLog.fromData(data);
}
}
return ApplicationLog;
} //end appLogService function
})();
@@ -0,0 +1,44 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an Account object, which defines the person who has
* authenticated with the server.
*/
angular.module('portal.common.services.model.cache')
.service('Config', configService);
function configService(Map) {
function Config(data) {
var config = this;
config.filepath = '';
config.dbUsername = '';
config.dbPassword = '';
config.dbRootUser = '';
config.dbRootPassword = '';
config.dbHost = '';
config.dbPort = 0;
config.userExpirationDays = 0;
config.logLevel = '';
config.fromData = function (data) {
config.filepath = data.filepath;
config.dbUsername = data.dbUsername;
config.dbPassword = data.dbPassword;
config.dbRootUser = data.dbRootUser;
config.dbRootPassword = data.dbRootPassword;
config.dbHost = data.dbHost;
config.dbPort = parseInt(data.dbPort);
config.userExpirationDays = parseInt(data.userExpirationDays);
config.logLevel = data.logLevel;
};
if (angular.isDefined(data)) {
config.fromData(data);
}
}
return Config;
} //end configService function
})();
@@ -0,0 +1,39 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an creds object
*/
angular.module('portal.common.services.model.cache')
.service('Credentials', credentialsService);
function credentialsService(Map) {
function Credentials(data) {
var creds = this;
creds.id = null;
creds.uid = '';
creds.username = '';
creds.password = '';
creds.name = '';
creds.credentialType = '';
creds.key = '';
creds.passphrase = '';
creds.fromData = function (data) {
creds.id = data.id;
creds.uid = data.uid;
creds.username = data.username;
creds.name = data.name;
creds.credentialType = data.credentialType;
creds.key = '';
creds.passphrase = '';
};
if (angular.isDefined(data)) {
creds.fromData(data);
}
}
return Credentials;
} //end credentialsService function
})();
@@ -0,0 +1,30 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an creds object
*/
angular.module('portal.common.services.model.cache')
.service('DropDownItem', dropDownService);
function dropDownService(Map) {
function DropDownItem(data) {
var creds = this;
creds.id = null;
creds.name = '';
creds.value = '';
creds.fromData = function (data) {
creds.id = data.id;
creds.name = data.name;
creds.value = data.value;
};
if (angular.isDefined(data)) {
creds.fromData(data);
}
}
return DropDownItem;
} //end dropDownService function
})();
@@ -0,0 +1,40 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an Account object, which defines the person who has
* authenticated with the server.
*/
angular.module('portal.common.services.model.cache')
.service('EmailTemplate', emailTmplService);
function emailTmplService(Map, Account) {
function EmailTemplate(data) {
var emailTmpl = this;
emailTmpl.id = null;
emailTmpl.emailName = '';
emailTmpl.emailSubject = '';
emailTmpl.emailMessage = '';
emailTmpl.scriptId = '';
emailTmpl.recipients = [];
emailTmpl.fromData = function (data) {
emailTmpl.id = data.id;
emailTmpl.emailName = data.emailName;
emailTmpl.emailSubject = data.emailSubject;
emailTmpl.emailMessage = data.emailMessage;
emailTmpl.scriptId = data.scriptId;
emailTmpl.recipients = [];
$.each(data.recipients, function(key, value){
emailTmpl.recipients.push(new Account(value));
});
};
if (angular.isDefined(data)) {
emailTmpl.fromData(data);
}
}
return EmailTemplate;
} //end emailTmplService function
})();
@@ -0,0 +1,42 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an creds object
*/
angular.module('portal.common.services.model.cache')
.service('GitInfo', gitInfoService);
function gitInfoService(Map, Credentials) {
function GitInfo(data) {
var gitInfo = this;
gitInfo.id = null;
gitInfo.name = '';
gitInfo.scm = '';
gitInfo.branch = '';
gitInfo.directory = '';
gitInfo.lastUpdated = null;
gitInfo.createDate = null;
gitInfo.createdBy = '';
gitInfo.credentials = null;
gitInfo.fromData = function (data) {
gitInfo.id = data.id;
gitInfo.name = data.name;
gitInfo.scm = data.scm;
gitInfo.branch = data.branch;
gitInfo.directory = data.directory;
gitInfo.credentials = new Credentials(data.credentials);
gitInfo.lastUpdated = data.lastUpdated;
gitInfo.createDate = data.createDate;
gitInfo.createdBy = data.createdBy;
};
if (angular.isDefined(data)) {
gitInfo.fromData(data);
}
}
return GitInfo;
} //end gitInfoService function
})();
@@ -0,0 +1,28 @@
(function () {
'use strict';
angular.module('portal.common.services.model.cache')
.service('HashType', hashTypeService);
function hashTypeService(Map) {
function HashType(data) {
var hash = this;
hash.id = null;
hash.name = '';
hash.displayName = '';
hash.valid = false;
hash.length = null;
if (angular.isDefined(data)) {
hash.id = data.id;
hash.name = data.name;
hash.displayName = data.displayName;
hash.valid = data.valid === 'true' || data.valid === true;
hash.length = parseInt(data.length);
}
}
return HashType;
}
})();
@@ -0,0 +1,30 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an Account object, which defines the person who has
* authenticated with the server.
*/
angular.module('portal.common.services.model.cache')
.service('LoggerInfo', loggerService);
function loggerService(Map) {
function LoggerInfo(data) {
var info = this;
info.logger = '';
info.level = '';
info.fromData = function (data) {
info.logger = data.logger;
info.level = data.level;
};
if (angular.isDefined(data)) {
info.fromData(data);
}
}
return LoggerInfo;
} //end configService function
})();
@@ -0,0 +1,85 @@
(function () {
'use strict';
angular.module('portal.common.services.model.cache')
.service('permissionObjects', permissionService);
function permissionService(Map) {
/* jshint validthis: true */
var permissionObjects = this;
this.PermissionGroup = function(data) {
this.id = null;
this.name = '';
this.displayName = '';
this.enabled = false;
this.permissions = [];
if (data) {
this.id = data.id;
this.name = data.name;
this.displayName = data.displayName;
this.enabled = data.enabled;
this.permissions = [];
if(data.permissions) {
for (var i = 0; i < data.permissions.length; i++) {
this.permissions.push(new permissionObjects.PermissionGroupPermission(data.permissions[i]));
}
}
}
};
this.PermissionGroupPermission = function(data) {
this.type = 'PermissionGroupPermission';
this.id = null;
this.permissionId = null;
this.permissionGroupId = null;
this.name = '';
this.displayName = '';
this.permissionCategory = '';
this.allowed = false;
if (data) {
this.type = 'PermissionGroupPermission';
this.id = data.id;
this.permissionId = data.permissionId;
this.permissionGroupId = data.permissionGroupId;
this.name = data.name;
this.displayName = data.displayName;
this.permissionCategory = data.permissionCategory;
this.allowed = data.allowed;
}
};
this.PermissionCategory = function(data) {
this.id = null;
this.name = '';
this.displayName = '';
this.permissions = [];
if (data) {
this.id = data.id;
this.name = data.name;
this.displayName = data.displayName;
this.permissions = [];
if (data.permissions) {
for (var i = 0; i < data.permissions.length; i++) {
this.permissions.push(new permissionObjects.Permission(data.permissions[i]));
}
}
}
};
this.Permission = function(data) {
this.type = 'Permission';
this.id = null;
this.name = '';
this.displayName = '';
this.permissionCategory = '';
if (data) {
this.id = data.id;
this.name = data.name;
this.displayName = data.displayName;
this.permissionCategory = data.permissionCategory;
}
};
} //end permissionService function
})();
@@ -0,0 +1,33 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an resource file object,
*/
angular.module('portal.common.services.model.cache')
.service('ResourceFile', resourceFileService);
function resourceFileService(Map) {
function ResourceFile(data) {
var resourceFile = this;
resourceFile.id = '';
resourceFile.fileName = '';
resourceFile.fileLocation = '';
resourceFile.fileType = '';
resourceFile.dateCreated = '';
resourceFile.valid = false;
if (angular.isDefined(data)) {
resourceFile.id = data.id;
resourceFile.fileName = data.fileName;
resourceFile.fileLocation = data.fileLocation;
resourceFile.fileType = data.fileType;
resourceFile.dateCreated = data.dateCreated;
resourceFile.valid = data.valid;
}
}
return ResourceFile;
} //end patchFileService function
})();
@@ -0,0 +1,207 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines an script object
*/
angular.module('portal.common.services.model.cache')
.service('scriptObjects', scriptService);
function scriptService(Map, Credentials, ResourceFile, EmailTemplate) {
/* jshint validthis: true */
var scriptObjects = this;
scriptObjects.Script = function (data) {
var script = this;
script.id = null;
script.name = '';
script.command = '';
script.baseDirectory = '';
script.outputDirectory = '';
script.scriptType = '';
script.parameters = [];
script.schedule = [];
script.scriptVariables = [];
script.scriptChain = [];
script.scriptEmails = [];
script.remote = null;
script.scp = null;
if (data) {
script.id = data.id;
script.name = data.name;
script.command = data.command;
script.baseDirectory = data.baseDirectory;
script.outputDirectory = data.outputDirectory;
script.scriptType = data.scriptType;
script.remote = new scriptObjects.ScriptRemote(data.remote);
script.scp = new scriptObjects.ScriptScp(data.scp);
script.parameters = [];
script.schedule = [];
script.scriptVariables = [];
script.scriptEmails = [];
$.each(data.parameters, function(key, value) {
script.parameters.push(new scriptObjects.ScriptParameter(value));
});
$.each(data.schedule, function(key, value) {
script.schedule.push(new scriptObjects.ScriptSchedule(value));
});
$.each(data.scriptVariables, function(key, value) {
script.scriptVariables.push(new scriptObjects.ScriptEnvironmentVariable(value));
});
$.each(data.scriptChain, function(key, value) {
script.scriptChain.push(new scriptObjects.ScriptChain(value));
});
$.each(data.scriptEmails, function(key, value) {
script.scriptEmails.push(new EmailTemplate(value));
});
}
};
scriptObjects.ScriptSchedule = function(data) {
var schedule = this;
schedule.id = null;
schedule.jobId = '';
schedule.startDatetime = moment().toDate();
schedule.endDatetime = null;
schedule.frequency = null;
schedule.maxExecutions = null;
schedule.currentExecutionCount = null;
schedule.lastRun = null;
schedule.script = null;
schedule.executionStatus = null;
if (data) {
schedule.id = data.id;
schedule.jobId = data.jobId;
schedule.startDatetime = data.startDatetime;
schedule.endDatetime = data.endDatetime;
schedule.frequency = data.frequency;
schedule.maxExecutions = data.maxExecutions;
schedule.currentExecutionCount = data.currentExecutionCount;
schedule.lastRun = data.lastRun;
schedule.script = data.script;
schedule.executionStatus = data.executionStatus;
}
};
scriptObjects.ScriptParameter = function(data) {
var param = this;
param.id = null;
param.parameter = '';
param.script = '';
if (data) {
param.id = data.id;
param.parameter = data.parameter;
param.script = data.script;
}
};
scriptObjects.ScriptChain = function(data) {
var chain = this;
chain.id = null;
chain.parentScript = undefined;
chain.childScript = undefined;
chain.executeAfterMin = undefined;
chain.exitStatus = undefined;
if (data) {
chain.id = data.id;
chain.parentScript = data.parentScript;
chain.childScript = data.childScript;
chain.executeAfterMin = data.executeAfterMin;
chain.exitStatus = data.exitStatus;
}
};
scriptObjects.ScriptEnvironmentVariable = function(data) {
var envVar = this;
envVar.id = null;
envVar.name = '';
envVar.value = '';
envVar.createdBy = null;
envVar.script = null;
envVar.lastUpdated = '';
envVar.dateCreated = '';
envVar.isNew = true;
if (data) {
envVar.id = data.id;
envVar.name = data.name;
envVar.value = data.value;
envVar.createdBy = data.createdBy;
envVar.script = data.script;
envVar.lastUpdated = data.lastUpdated;
envVar.dateCreated = data.dateCreated;
envVar.isNew = false;
}
};
scriptObjects.ScriptStatus = function(data) {
var status = this;
status.id = undefined;
status.exitStatus = undefined;
status.results = '';
status.startTime = undefined;
status.endTime = undefined;
status.resourceFiles = [];
if (data) {
status.id = data.id;
status.exitStatus = data.exitStatus;
status.results = data.results;
status.startTime = data.startTime;
status.endTime = data.endTime;
if (data.resourceFiles) {
$.each(data.resourceFiles, function(key, value) {
status.resourceFiles.push(new ResourceFile(value));
});
}
}
};
scriptObjects.ScriptRemote = function(data) {
var remote = this;
remote.scriptId = undefined;
remote.scriptCredentials = null;
remote.url = undefined;
remote.port = undefined;
if (data) {
remote.scriptId = data.scriptId;
remote.url = data.url;
remote.port = data.port;
if (data.scriptCredentials) {
remote.scriptCredentials = new Credentials(data.scriptCredentials);
}
}
};
scriptObjects.ScriptScp = function(data) {
var scp = this;
scp.id = undefined;
scp.scriptId = undefined;
scp.fromHost = '';
scp.fromPort = 0;
scp.toHost = '';
scp.toPort = 0;
scp.dataRegex = '';
scp.toCredentials = undefined;
scp.fromCredentials = undefined;
if (data) {
scp.id = data.id;
scp.scriptId = data.scriptId;
scp.fromHost = data.fromHost;
scp.fromPort = data.fromPort;
scp.toHost = data.toHost;
scp.toPort = data.toPort;
scp.dataRegex = data.dataRegex;
if (data.toCredentials) {
scp.toCredentials = new Credentials(data.toCredentials);
}
if (data.fromCredentials) {
scp.fromCredentials = new Credentials(data.fromCredentials);
}
}
};
} //end scriptService function
})();
@@ -0,0 +1,75 @@
(function () {
'use strict';
/**
* DESCRIPTION:
*/
angular.module('portal.common.services.model.cache')
.service('UploadFile', uploadFileService);
function uploadFileService() {
function UploadFile() {
var file = this;
file.name = '';
file.fileSize = null;
file.guid = '';
file.url = '';
file.rawFile = null;
file.uploadProgress = 0;
file.percentComplete = 0;
file.uploaded = null;
file.reason = '';
file.trackUploadProcessing = false;
file.uploadMax = 0;
file.init = function (rawFile, trackUploadProcessing) {
file.trackUploadProcessing = trackUploadProcessing;
file.rawFile = rawFile;
file.name = rawFile.name;
file.fileSize = rawFile.size;
// The file.uploadMax represents when the file upload is complete. If tracking upload
// processing, the server sends percent complete values as triggers periodically so the max is 100 (%).
// Otherwise, just track the uploaded byte progress so the max is the file size.
file.uploadMax = trackUploadProcessing ? 100 : file.fileSize;
file.type = rawFile.type;
return file;
};
file.uploaded = function (data, baseURI) {
file.uploaded = true;
baseURI = baseURI === undefined ? '' : baseURI;
if (data !== undefined) {
file.name = data.original_name; //jshint ignore:line
file.fileSize = data.file_size; //jshint ignore:line
file.guid = data.guid;
file.url = baseURI + data.guid;
file.uploadProgress = file.fileSize;
}
return file;
};
file.setUploadProgress = function (uploadProgress) {
file.uploadProgress = uploadProgress;
file.percentComplete = Math.min(Math.floor((file.uploadProgress / file.fileSize) * 100), 100);
};
file.uploadFailed = function (reason) {
file.uploaded = false;
file.reason = reason;
if (reason === undefined) {
file.reason = 'unknown failure';
}
};
file.finished = function () {
return file.uploaded === true ? true : false;
};
file.inProgress = function () {
return file.upload === null;
};
file.failed = function () {
return file.uploaded === false ? true : false;
};
}
return UploadFile;
} //end uploadFileService function
})();
@@ -0,0 +1,137 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines a store, or access point to get data out of the cache and from an external source.
*/
angular.module('portal.common.services.model.cache')
.service('Store', storeService);
function storeService($timeout, Box) {
var cache = null;
/**
* Store defines the information required to access data from the cache (id) and
* pull it from an external source if it hasn't been pulled.
* @param {type} args {id: '', source: function}
* @returns {store_L35.storeService.Store}
*/
function Store(args) {
var store = this;
/**Attach the args and a few for convenience directly to the Store (below). */
store.args = args;
/**
* Unique ID for this store, this will be the . accessor on the mini cache.
*/
store.id = args.id;
/**
* A function with registerable callback that provides the data.
*/
store.source = args.source;
/**
* Empty params object, used in conjunction with Id to generate unique key for store.
* Passed in to the source as the args.
* @type Number|Number
*/
store.params = args.params;
/**
* Key used for accessing data from the cache.
*/
store.key = getKey();
/**
* Reference to the box accessed by the key.
*/
store.box = cache.get(store.key);
/**
* Listeners for this store to unsubscribe.
*/
store.boxListener = null;
/**
* Registers a callback to be notified of data changes. If the data has not been initialized it is
* initialized, once and only once. Subsequent data changes
* @param {type} callback
* @returns {unresolved}
*/
store.init = function () {
store.boxListener = store.box.init();
return store.boxListener;
};
/**
* Forces a refresh from source.
* @returns {undefined}
*/
store.refresh = function () {
var box = store.getBox();
return box.refresh();
};
/**
* Updates store on the cache, and notifies listeners.
* Could be called to update data on trigger.
* @param {type} data
* @returns {undefined}
*/
store.update = function (data) {
store.getBox().update(data);
};
/**
* @returns {Boolean} True if ready, false if pending or not initialized.
*/
store.isReady = function () {
return store.getBox().isDone();
};
store.getBox = function () {
return store.box;
};
store.unlisten = function () {
if (store.boxListener !== null) {
store.boxListener.unlisten();
}
};
store.getParams = function () {
return store.params;
};
function getKey() {
var key = store.id;
for (var i in store.params) {
key += '_' + i + '_' + store.params[i];
}
/**
* Init box if doesn't already exist.
* Box persists between instnaces.
*/
if (!angular.isDefined(cache.get(key))) {
cache.put(key, new Box(args));
}
return key;
}
}
/**
* Static function for registering the cache.
* @param {type} _cache
* @returns {undefined}
*/
Store.registerCache = function (_cache) {
cache = _cache;
};
Store.notifyStores = function(stores) {
for (var i in stores) {
stores[i].getBox().notify();
}
};
return Store;
} //end storeService function
})();
@@ -0,0 +1,60 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('accountStores', accountStoresService);
function accountStoresService(stores, Store, Account, accountProvider, triggerManager, Triggers, Map) {
var accountStores = {
Account: stores.inherit('account', function () {
Store.call(this, {
id: 'account',
source: accountProvider.isLoggedIn,
processGui: function (data) {
var act = new Account(data);
triggerManager.subscribe(act.stompTopics);
return act;
}});
}),
UserPool: stores.inherit('userPool', function(){
Store.call(this, {
id: 'userPool',
source: accountProvider.getAllUsers,
processGui: function(data) {
return Map.create(data, Account, 'id');
}
});
}),
};
Triggers.listen([Triggers.USER_ADDED], function(trigger, payload){
var data = payload.resources;
var users = new accountStores.UserPool();
if (users.isReady()) {
for (var i = 0; i < data.length; i++) {
var user = new Account(data[i]);
users.getBox().data.put(user.id, user);
}
users.getBox().notify();
}
});
Triggers.listen([Triggers.USER_DELETED], function(trigger, payload){
var data = payload.resources;
var users = new accountStores.UserPool();
if (users.isReady()) {
for (var i = 0; i < data.length; i++) {
var user = new Account(data[i]);
users.getBox().data.removeByKey(user.id, user);
}
users.getBox().notify();
}
});
return accountStores;
} //end accountStoresService function
})();
@@ -0,0 +1,33 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('appLogStores', appLogStoresService);
function appLogStoresService(stores, Store, ApplicationLog, appLogProvider, Map, Triggers) {
var appLogStores = {
Logs: stores.inherit('logs', function(){
Store.call(this, {
id: 'logs',
source: appLogProvider.getAllLogs,
processGui: function(data) {
return Map.create(data, ApplicationLog, 'id');
}
});
}),
};
Triggers.listen([Triggers.APP_LOGS_UPDATED, Triggers.APP_LOGS_PURGED], function(trigger, payload){
var data = payload.resources;
var logs = new appLogStores.Logs();
if (logs.isReady()) {
logs.getBox().refresh();
}
});
return appLogStores;
} //end accountStoresService function
})();
@@ -0,0 +1,35 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('configStores', configStoresService);
function configStoresService(stores, Store, Config, configProvider, Map) {
var copnfigStores = {
Configs: stores.inherit('configs', function () {
Store.call(this, {
id: 'configs',
source: configProvider.getConfiguration,
processGui: function (data) {
var act = new Config(data);
return act;
}});
}),
Config: stores.inherit('config', function (configKey) {
Store.call(this, {
id: 'config',
source: configProvider.getConfigurationValue,
params: configKey,
processGui: function (data) {
var conf = new Config(data);
return conf;
}});
}),
};
return copnfigStores;
} //end configStoresService function
})();
@@ -0,0 +1,34 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('credentialStores', credentialStoresService);
function credentialStoresService(stores, Store, Credentials, credentialProvider, Map, DropDownItem) {
var credentialsStores = {
Credentials: stores.inherit('credentials', function () {
Store.call(this, {
id: 'credentials',
source: credentialProvider.getCredentials,
processGui: function (data) {
var map = Map.create(data, Credentials, 'uid');
return map;
}});
}),
CredentialTypes: stores.inherit('credentialTypes', function(){
Store.call(this, {
id: 'credentialTypes',
source: credentialProvider.getCredentialTypes,
processGui: function(data) {
return Map.create(data, DropDownItem, 'id');
}
});
}),
};
return credentialsStores;
} //end credentialsStoresService function
})();
@@ -0,0 +1,25 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('gitStores', gitStoresService);
function gitStoresService(stores, Store, GitInfo, gitProvider, Map) {
var gitStores = {
Repos: stores.inherit('repos', function () {
Store.call(this, {
id: 'repos',
source: gitProvider.getAllRepos,
processGui: function (data) {
var map = Map.create(data, GitInfo, 'id');
return map;
}});
}),
};
return gitStores;
} //end gitStoresService function
})();
@@ -0,0 +1,26 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('loggerStores', loggerStoreService);
function loggerStoreService(stores, Store, LoggerInfo, loggerProvider, Map) {
var loggerStores = {
Loggers: stores.inherit('loggers', function(){
Store.call(this, {
id: 'loggers',
source: loggerProvider.getLoggers,
processGui: function(data) {
return Map.create(data, LoggerInfo, 'logger');
}
});
})
};
return loggerStores;
} //end loggerStopresService function
})();
@@ -0,0 +1,65 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('permissionStores', permissionStoresService);
function permissionStoresService(stores, Store, permissionObjects, permissionProvider, triggerManager, Triggers, Map) {
var permissionStores = {
PermissionGroups: stores.inherit('permissionGroups', function () {
Store.call(this, {
id: 'permissionGroups',
source: permissionProvider.getPermissionGroups,
processGui: function (data) {
return Map.create(data, permissionObjects.PermissionGroup, 'id');
}});
}),
AllPermissionGroups: stores.inherit('allPermissionGroups', function () {
Store.call(this, {
id: 'allPermissionGroups',
source: permissionProvider.getAllPermissionGroups,
processGui: function (data) {
return Map.create(data, permissionObjects.PermissionGroup, 'id');
}});
}),
PermissionCategories: stores.inherit('permissionCategories', function () {
Store.call(this, {
id: 'permissionCategories',
source: permissionProvider.getPermissionCategories,
processGui: function (data) {
return Map.create(data, permissionObjects.PermissionCategory, 'id');
}});
})
};
Triggers.listen([Triggers.PERMISSIONS_CHANGED, Triggers.PERMISSIONS_ADDED, Triggers.PERMISSIONS_UPDATED], function(trigger, payload){
var data = payload.resources;
var permGroups = new permissionStores.PermissionGroups();
if (permGroups.isReady()) {
for (var i = 0; i < data.length; i++) {
var permGroup = new permissionObjects.PermissionGroup(data[i]);
permGroups.getBox().data.put(permGroup.id, permGroup);
}
permGroups.getBox().notify();
}
});
Triggers.listen([Triggers.PERMISSIONS_DELETED], function(trigger, payload){
var data = payload.resources;
var permGroups = new permissionStores.PermissionGroups();
if (permGroups.isReady()) {
for (var i = 0; i < data.length; i++) {
var permGroup = new permissionObjects.PermissionGroup(data[i]);
permGroups.getBox().data.removeByKey(permGroup.id, permGroup);
}
permGroups.getBox().notify();
}
});
return permissionStores;
} //end permissionStoresService function
})();
@@ -0,0 +1,33 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for resource file.
*/
angular.module('portal.common.services.model.cache')
.service('resourceFileStores', resourceFileStoresService);
function resourceFileStoresService(stores, Store, ResourceFile, fileProvider, Map) {
var resourceFileStores = {
PatchFiles: stores.inherit('patchFiles', function (args) {
Store.call(this, {
id: 'patchFiles',
source: fileProvider.getAllFiles,
processGui: function (data) {
return Map.create(data, ResourceFile, 'id');
}});
}),
Directories: stores.inherit('patchDirectories', function () {
Store.call(this, {
id: 'patchDirectories',
source: fileProvider.getDirectories,
processGui: function (data) {
return data;
}});
}),
};
return resourceFileStores;
} //end patchFileStoresService function
})();
@@ -0,0 +1,130 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('scriptStores', scriptStoresService);
function scriptStoresService(stores, Store, scriptObjects, scriptProvider, DropDownItem, Map, Triggers, portalUtils) {
var scriptStores = {
Scripts: stores.inherit('scripts', function(){
Store.call(this, {
id: 'scripts',
source: scriptProvider.getAllScripts,
processGui: function(data) {
return Map.create(data, scriptObjects.Script, 'id');
}
});
}),
ScriptTypes: stores.inherit('scriptTypes', function(){
Store.call(this, {
id: 'scriptTypes',
source: scriptProvider.getScriptType,
processGui: function(data) {
return Map.create(data, DropDownItem, 'id');
}
});
}),
ScheduleFrequencies: stores.inherit('scheduleFrequencies', function(){
Store.call(this, {
id: 'scheduleFrequencies',
source: scriptProvider.getScheduleFrequencies,
processGui: function(data) {
return Map.create(data, DropDownItem, 'id');
}
});
}),
ScriptStatus: stores.inherit('scriptStatus', function(jobId){
Store.call(this, {
id: 'scriptStatus',
source: scriptProvider.getScriptStatus,
params: jobId,
processGui: function(data) {
return Map.create(data, scriptObjects.ScriptStatus, 'id');
}
});
})
};
Triggers.listen([Triggers.SCRIPT_ADDED, Triggers.SCRIPT_UPDATED], function(trigger, payload){
var data = payload.resources;
var scripts = new scriptStores.Scripts();
if (scripts.isReady()) {
for (var i = 0; i < data.length; i++) {
var script = new scriptObjects.Script(data[i]);
scripts.getBox().data.put(script.id, script);
}
scripts.getBox().notify();
}
});
Triggers.listen([Triggers.SCRIPT_DELETED], function(trigger, payload){
var data = payload.resources;
var scripts = new scriptStores.Scripts();
if (scripts.isReady()) {
for (var i = 0; i < data.length; i++) {
var script = new scriptObjects.Script(data[i]);
scripts.getBox().data.removeByKey(script.id, script);
}
scripts.getBox().notify();
}
});
Triggers.listen([Triggers.SCRIPT_SCHEDULE_DELETED], function(trigger, payload){
var data = payload.resources;
var scripts = new scriptStores.Scripts();
var schedule = new scriptObjects.ScriptSchedule(data[0]);
if (scripts.isReady()) {
var scriptBox = scripts.getBox().data.values;
for (var i = 0; i < scriptBox.length; i++) {
if(schedule.script === scriptBox[i].id) {
for (var j = 0; j < scriptBox[i].schedule.length; j++) {
if (schedule.jobId === scriptBox[i].schedule[j].jobId) {
scriptBox[i].schedule.splice(j, 1);
break;
}
}
break;
}
}
scripts.getBox().notify();
}
});
Triggers.listen([Triggers.SCRIPT_COMPLETED], function(trigger, payload) {
if (!payload.resources) {
return;
}
var data = payload.resources;
var scripts = new scriptStores.Scripts();
var script = new scriptObjects.Script(data[1]);
if (scripts.isReady()) {
var scriptsBox = scripts.getBox().data.values;
for (var x = 0; x < scriptsBox.length; x++) {
if (scriptsBox[x].id === script.id) {
scriptsBox[x].schedule = script.schedule;
}
}
scripts.getBox().notify();
}
var scriptName = script.name;
var jobId = data[0];
var statusStr = 'Failed';
for (var j = 0; j < script.schedule.length; j++) {
var sched = script.schedule[j];
if (sched.jobId === jobId && sched.executionStatus === 0) {
statusStr = 'Success';
break;
}
}
portalUtils.toast('Script ' + scriptName +' completed with status of ' + statusStr, ['top', 'left'], 2000);
});
return scriptStores;
} //end scriptStoresService function
})();
@@ -0,0 +1,27 @@
(function () {
'use strict';
/**
* DESCRIPTION: Provides accessors to the cache(cacheService) getting data if
* it doesn't exist, providing promises to the data, and notification when
* the data changes.
*
*/
angular.module('portal.common.services.model.cache')
.service('stores', storesService);
function storesService(Store, $log, portalUtils) {
var stores = {};
return {
inherit: function (id, ChildStore) {
if (angular.isDefined(stores[id])) {
$log.error('Duplicate store with id - ' + id);
} else {
stores[id] = portalUtils.inherit(ChildStore, Store);
return stores[id];
}
}
};
} //end storesService function
})();
@@ -0,0 +1,92 @@
(function () {
'use strict';
/**
* DESCRIPTION: Stores for account.
*/
angular.module('portal.common.services.model.cache')
.service('systemStores', systemStoresService);
function systemStoresService(stores, Store, scriptObjects, systemProvider, Map, EmailTemplate, Triggers) {
var systemStores = {
EnvironmentVariables: stores.inherit('envvars', function(){
Store.call(this, {
id: 'envvars',
source: systemProvider.getAllEnvVars,
processGui: function(data) {
return Map.create(data, scriptObjects.ScriptEnvironmentVariable, 'id');
}
});
}),
SMTPConfig: stores.inherit('smtpConfig', function(){
Store.call(this, {
id: 'smtpConfig',
source: systemProvider.getSmtpConfig,
processGui: function(data) {
return Map.create(data, scriptObjects.ScriptEnvironmentVariable, 'id');
}
});
}),
EmailTemplates: stores.inherit('emailTmpls', function(){
Store.call(this, {
id: 'emailTmpls',
source: systemProvider.getEmailTemplates,
processGui: function(data) {
return Map.create(data, EmailTemplate, 'id');
}
});
}),
};
Triggers.listen([Triggers.EMAIL_TEMPLATE_UPDATED], function(trigger, payload){
var data = payload.resources;
var tmpls = new systemStores.EmailTemplates();
if (tmpls.isReady()) {
for (var i = 0; i < data.length; i++) {
var tmpl = new EmailTemplate(data[i]);
tmpls.getBox().data.put(tmpl.id, tmpl);
}
tmpls.getBox().notify();
}
});
Triggers.listen([Triggers.EMAIL_TEMPLATE_DELETED], function(trigger, payload){
var data = payload.resources;
var tmpls = new systemStores.EmailTemplates();
if (tmpls.isReady()) {
for (var i = 0; i < data.length; i++) {
var tmpl = new EmailTemplate(data[i]);
tmpls.getBox().data.removeByKey(tmpl.id, tmpl);
}
tmpls.getBox().notify();
}
});
Triggers.listen([Triggers.ENV_VARS_ADDED], function(trigger, payload){
var data = payload.resources;
var envvars = new systemStores.EnvironmentVariables();
if (envvars.isReady()) {
for (var i = 0; i < data.length; i++) {
var envvar = new scriptObjects.ScriptEnvironmentVariable(data[i]);
envvars.getBox().data.put(envvar.id, envvar);
}
envvars.getBox().notify();
}
});
Triggers.listen([Triggers.ENV_VARS_DELETED], function(trigger, payload){
var data = payload.resources;
var envvars = new systemStores.EnvironmentVariables();
if (envvars.isReady()) {
for (var i = 0; i < data.length; i++) {
var envvar = new scriptObjects.ScriptEnvironmentVariable(data[i]);
envvars.getBox().data.removeByKey(envvar.id, envvar);
}
envvars.getBox().notify();
}
});
return systemStores;
} //end systemStoresService function
})();
@@ -0,0 +1,76 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('accountProvider', accountProviderService);
function accountProviderService(rest, Account) {
var baseUrl = '/account';
return {
isLoggedIn: function () {
return rest.get({
id: baseUrl + '/isLoggedIn.do',
convert: function (data) {
return new Account(data);
}
});
},
getAllUsers: function() {
return rest.get({
id: baseUrl + '/getAll.do',
});
},
/**
* Login.
* @param {type} args password, username
* @returns {undefined}
*/
login: function (username, password) {
return rest.put({
id: baseUrl + '/login.do',
block: true,
data: {username: username, password: password}
});
},
/**
* Logout.
* @param {type}
* @returns {undefined}
*/
logout: function () {
return rest.put({
id: baseUrl + '/logout.do'
});
},
addUser: function(user) {
return rest.put({
id: baseUrl + '/addUser.do',
data: user
});
},
deleteUser: function(user) {
return rest.put({
id: baseUrl + '/deleteUser.do',
data: user
});
},
getRoleData: function(data) {
return rest.put({
id: baseUrl + '/getRoleData.do',
data: {type: data}
});
},
getUserInfo: function(args) {
return rest.get({
id: baseUrl + '/getUserInfo.do',
data: args,
cache: false
});
}
};
} //end accountProviderService function
})();
@@ -0,0 +1,26 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('appLogProvider', appLogProviderService);
function appLogProviderService(rest) {
var baseUrl = '/logs';
return {
getAllLogs: function () {
return rest.get({
id: baseUrl + '/getAll.do',
});
},
purgeLogs: function(date) {
return rest.post({
id: baseUrl + '/purge.do',
data: date
});
}
};
} //end configProviderService function
})();
@@ -0,0 +1,33 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('configProvider', configProviderService);
function configProviderService(rest, Config) {
var baseUrl = '/config';
return {
getConfiguration: function () {
return rest.get({
id: baseUrl + '/getConfiguration.do',
});
},
getConfigurationValue: function (value) {
return rest.get({
id: baseUrl + '/getConfigurationValue.do',
data: value
});
},
saveConfiguration: function(config) {
return rest.put({
id: baseUrl + '/saveConfiguration.do',
data:config
});
}
};
} //end configProviderService function
})();
@@ -0,0 +1,38 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('credentialProvider', credentialProviderService);
function credentialProviderService(rest, Credentials) {
var baseUrl = '/creds';
return {
addCredentials: function (args) {
return rest.put({
id: baseUrl + '/add.do',
data: args,
});
},
getCredentials : function() {
return rest.get({
id: baseUrl + '/get.do'
});
},
deleteCredentials: function(entity) {
return rest.put({
id: baseUrl + '/delete.do',
data: entity
});
},
getCredentialTypes: function() {
return rest.get({
id: baseUrl + '/getCredentialTypes.do'
});
}
};
} //end accountProviderService function
})();
@@ -0,0 +1,22 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the file server module.
*/
angular.module('portal.common.services.model.rest')
.factory('fileProvider', fileProviderService);
function fileProviderService(rest) {
var baseUrl = '/file';
return {
deleteFile: function(resourceFile) {
return rest.put({
id: baseUrl + '/delete.do',
data: resourceFile
});
}
};
} //end fileProviderService function
})();
@@ -0,0 +1,39 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the git server module.
*/
angular.module('portal.common.services.model.rest')
.factory('gitProvider', gitProviderService);
function gitProviderService(rest, GitInfo) {
var baseUrl = '/git';
return {
addGitRepo: function(gitInfo) {
return rest.put({
id: baseUrl + '/add.do',
data: gitInfo
});
},
getAllRepos : function() {
return rest.get({
id: baseUrl + '/getAll.do'
});
},
deleteRepo: function(entity) {
return rest.put({
id: baseUrl + '/delete.do',
data: entity
});
},
pullRepo: function(entity) {
return rest.put({
id: baseUrl + '/pull.do',
data: entity
});
}
};
} //end gitProviderService function
})();
@@ -0,0 +1,27 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the logger provider server module.
*/
angular.module('portal.common.services.model.rest')
.factory('loggerProvider', loggerProviderSerice);
function loggerProviderSerice(rest, Config) {
var baseUrl = '/logger';
return {
getLoggers: function () {
return rest.get({
id: baseUrl + '/getLoggers.do',
});
},
setLoggers: function(loggers) {
return rest.put({
id: baseUrl + '/setLoggers.do',
data: loggers
});
}
};
} //end loggerProviderSerice function
})();
@@ -0,0 +1,42 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the permissions server module.
*/
angular.module('portal.common.services.model.rest')
.factory('permissionProvider', permissionProviderService);
function permissionProviderService(rest) {
var baseUrl = '/permissions';
return {
getPermissionGroups: function () {
return rest.get({
id: baseUrl + '/getPermissionGroups.do',
});
},
getAllPermissionGroups: function () {
return rest.get({
id: baseUrl + '/getAll.do',
});
},
getPermissionCategories: function () {
return rest.get({
id: baseUrl + '/getPermissionCategories.do',
});
},
updatePermissions: function (isNew, args) {
return rest.put({
id: baseUrl + (isNew ? '/addPermssionCategory.do' : '/updatePermissionCategory.do'),
data: args
});
},
deletePermissionGroup: function (args) {
return rest.put({
id: baseUrl + '/deletePermissionGroup.do',
data: args
});
}
};
} //end permissionProviderService function
})();
@@ -0,0 +1,177 @@
(function () {
'use strict';
/**
* DESCRIPTION: Describes a server rest request.
* Defines the promise where data is returned.
*/
angular.module('portal.common.services.model.rest')
.factory('Request', requestService);
function requestService($http, $q, $rootScope, $window) {
/**
* Request Object and promise.
* @param {type} requestData {id, params, data}
*/
function Request(args) {
var request = this;
var deferred = $q.defer();
request.id = args.id;
request.params = args.params;
request.data = args.data;
request.process = args.process;
request.cache = args.cache ? true : false;
request.payload = null;
request.block = args.block;
function apply() {
if (request.block) {
$rootScope.loadingBlock = true;
}
//angular.toJson(request.data);
$http({
method: 'POST',
url: Request.baseURI + request.id,
params: request.params,
headers: {'Content-Type': Request.jsonContentType, 'dataType': Request.jsonDataType},
data: request.data,
cache: request.cache
}).then(onSuccess, onError).catch(onError);
return deferred.promise;
}
/**
* Handler for the $http request.
* @param {type} returnData
* @returns {undefined}
*/
function onSuccess(returnData, status, header, config) {
if (returnData.data) {
if (returnData.data.hasOwnProperty('body')) {
doSuccessSequence(returnData.data.body);
} else {
doSuccessSequence(returnData.data);
}
} else {
doErrorSequence(returnData.data, returnData.status);
}
$rootScope.loadingBlock = false;
}
/**
* Handles the sequence of callbacks for the success path.
* @param {type} data
* @returns {undefined}
*/
function doSuccessSequence(data) {
request.payload = data;
if (request.process) {
request.payload = request.process(data);
}
deferred.resolve(request.payload);
}
/**
* Handler for $http request.
* @param {type} data
* @returns {undefined}
*/
function onError(data, status, header, config) {
doErrorSequence(data.data, data.status);
$rootScope.loadingBlock = false;
}
/**
* Handles the sequence of callbacks for the error path.
* @param {type} data
* @returns {undefined}
*/
function doErrorSequence(data, status) {
request.payload = data;
// if we've made a rest call and go to the login page, redirect
if (!data.hasOwnProperty('success') && status !== 400) {
$window.location.reload();
}
deferred.reject(request.payload);
}
/**
* Puts the data on the server.
* @returns {request_L35.requestService.Request}
*/
request.put = function () {
return apply();
};
/**
* Gets data from the server. (could retry in the future).
* @returns {request_L35.requestService.Request}
*/
request.get = function () {
return apply();
};
request.upload = function () {
var promises = [];
var files = request.data;
var params = request.params;
//Angular doesn't support progress, so we use JQUERY instead.
function sendUpload(file) {
var deferred = $q.defer();
var formData = new FormData();
formData.append('file', file.rawFile);
if (params !== undefined) {
$.each(params, function(key, value) {
formData.append(key, value);
});
}
$http({
method: 'POST',
url: Request.baseURI + request.id,
data: formData,
cache: false,
transformRequest: angular.identity,
headers: {'Content-Type': undefined, 'dataType': undefined}
}).then(onUploadSuccess, onUploadError).catch(onUploadError);
function onUploadError(data, status, header, config) {
file.uploadFailed(data.data.message);
deferred.reject(angular.fromJson(data.data));
}
function onUploadSuccess(data, status, header, config) {
var returnData = data.data;
if (returnData.success) {
if (returnData.body.length === 0) {
return;
}
file.uploaded(returnData.body[0], Request.baseURI + '/');
file.response = returnData.body;
deferred.resolve(file);
} else {
file.uploadFailed(returnData.message);
deferred.reject();
}
}
return deferred.promise;
}
//Server only supports a single file.
for (var i = 0; i < files.length; i++) {
promises.push(sendUpload(files[i]));
}
return $q.all(promises);
};
}
Request.registerCache = function (cache) {
$http.defaults.cache = cache;
};
// TEMPORARY: should be unneeded when this file is being served from baseURI
Request.baseURI = '/portal';
Request.jsonContentType = 'application/json; charset=utf-8';
Request.jsonDataType = 'json';
return Request;
} //end requestService function
})();
@@ -0,0 +1,38 @@
(function () {
'use strict';
/**
* DESCRIPTION: Contains wrappers for the request obejct to simplify/force
* the different calls to pick either get/put and facilitate different behavior for each of them.
*/
angular.module('portal.common.services.model.rest', ['ui.router'])
.service('rest', restService);
function restService(Request) {
return {
/**
* Wraps/creates a request that gets data from the server.
* @param {type} request
* @returns {unresolved}
*/
get: function (args) {
return new Request(args).get();
},
/**
* Wraps/creates a request that commits data to the server.
* @param {type} request
* @returns {unresolved}
*/
put: function (args) {
return new Request(args).put();
},
post: function(args) {
return new Request(args).put();
},
upload: function (args) {
return new Request(args).upload();
}
};
} //end restService function
})();
@@ -0,0 +1,64 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('scriptProvider', scriptProviderService);
function scriptProviderService(rest, scriptObjects) {
var baseUrl = '/scripts';
return {
runScript: function(script) {
return rest.put({
id: baseUrl + '/runScript.do',
data: script
});
},
addScript: function(script) {
var endPoint = '/addScript.do';
if (script.id !== undefined && script.id !== null) {
endPoint = '/updateScript.do';
}
return rest.put({
id: baseUrl + endPoint,
data: script
});
},
getScriptStatus: function(jobId) {
return rest.put({
id: baseUrl + '/getScriptScheduleStatus.do',
data: jobId
});
},
deleteScript: function(script) {
return rest.put({
id: baseUrl + '/deleteScript.do',
data: script
});
},
deleteScriptSchedule: function(scriptSched) {
return rest.put({
id: baseUrl + '/deleteScriptSchedule.do',
data: scriptSched
});
},
getAllScripts: function() {
return rest.get({
id: baseUrl + '/getAll.do'
});
},
getScheduleFrequencies: function() {
return rest.get({
id: baseUrl + '/getScheduleFrequencies.do'
});
},
getScriptType: function() {
return rest.get({
id: baseUrl + '/getScriptType.do'
});
}
};
} //end scriptProviderService function
})();
@@ -0,0 +1,90 @@
(function () {
'use strict';
/**
* DESCRIPTION: Defines the restful calls for the account server module.
*/
angular.module('portal.common.services.model.rest')
.factory('systemProvider', scriptProviderService);
function scriptProviderService(rest, scriptObjects) {
var baseUrl = '/system';
return {
addEnvVars: function(envVars) {
var endPoint = '/addEnvVars.do';
var arrayItems = [];
if (!angular.isArray(envVars)) {
arrayItems.push(envVars);
} else {
arrayItems = envVars;
}
return rest.put({
id: baseUrl + endPoint,
data: arrayItems
});
},
updateSeed: function(seed) {
var endPoint = '/updateSeed.do';
return rest.put({
id: baseUrl + endPoint,
data: seed
});
},
updateSmtpConfig: function(smtpConf) {
var endPoint = '/updateSmtpConfig.do';
var arrayItems = [];
if (!angular.isArray(smtpConf)) {
arrayItems.push(smtpConf);
} else {
arrayItems = smtpConf;
}
return rest.put({
id: baseUrl + endPoint,
data: arrayItems
});
},
deleteEnvVar: function(envVars) {
var endPoint = '/deleteEnvVars.do';
var arrayItems = [];
if (!angular.isArray(envVars)) {
arrayItems.push(envVars);
} else {
arrayItems = envVars;
}
return rest.put({
id: baseUrl + endPoint,
data: arrayItems
});
},
getAllEnvVars: function() {
return rest.get({
id: baseUrl + '/getAll.do'
});
},
getSmtpConfig: function() {
return rest.get({
id: baseUrl + '/getSmtpConfig.do'
});
},
addEmailTemplate: function(tmpl) {
return rest.get({
id: baseUrl + '/addEmailTemplate.do',
data: tmpl
});
},
getEmailTemplates: function() {
return rest.get({
id: baseUrl + '/getEmailTemplates.do'
});
},
deleteEmailTemplates: function(tmpl) {
return rest.get({
id: baseUrl + '/deleteEmailTemplate.do',
data: tmpl
});
},
};
} //end scriptProviderService function
})();
@@ -0,0 +1,40 @@
angular.module('portal').factory('permissions', permissionFactory);
function permissionFactory($rootScope, $state, portalUtils, $q, cache, accountStores, Triggers) {
Triggers.listen([Triggers.PERMISSIONS_CHANGED], function(trigger, payload){
new accountStores.Account().refresh();
$rootScope.$broadcast('permissionsChanged');
});
var permissions = {
canView: function (attrs) {
var deferred = $q.defer();
//Nothing defined (always true)
if (angular.isDefined(attrs) === false) {
deferred.resolve(true);
} else {
var mCache = cache.request([new accountStores.Account()]).then(function () {
var validRole = verifyRole(mCache, attrs);
deferred.resolve(validRole);
});
}
return deferred.promise;
}
};
/**
* Check that the user is one of the passed in roles
* @param {type} attrs attributes to check against
* @returns {Boolean}
*/
function verifyRole(mCache, attrs) {
var show = true;
if (angular.isDefined(attrs.permission)) {
show = mCache.account.data.hasPermission(attrs.permission);
}
return show;
}
return permissions;
}
Loaded 100 of 511 files, more files were not shown because too many files have changed in this diff. Show more