Skip to content

Commit

Permalink
Support EnvFrom in the Env Editors
Browse files Browse the repository at this point in the history
Add dropdown support to give the ability to add bulk additions within
the environment editors
  • Loading branch information
cdcabrera committed Sep 22, 2017
1 parent be4c893 commit 71ac457
Show file tree
Hide file tree
Showing 7 changed files with 1,073 additions and 608 deletions.
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ <h1>JavaScript Required</h1>
<script src="scripts/directives/deleteLink.js"></script>
<script src="scripts/directives/editWebhookTriggers.js"></script>
<script src="scripts/directives/editConfigMap.js"></script>
<script src="scripts/directives/editEnvironmentFrom.js"></script>
<script src="scripts/directives/events.js"></script>
<script src="scripts/directives/eventsSidebar.js"></script>
<script src="scripts/directives/eventsBadge.js"></script>
Expand Down
195 changes: 195 additions & 0 deletions app/scripts/directives/editEnvironmentFrom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
"use strict";
(function() {
angular.module("openshiftConsole").component('editEnvironmentFrom', {
controller: [
'$attrs',
'$filter',
'$scope',
'keyValueEditorUtils',
EditEnvironmentFrom
],
//controllerAs: 'ctrl',
bindings: {
addRowLink: '@',
entries: '=',
envFromSelectorOptions: '<',
selectorPlaceholder: '@'
},
templateUrl: 'views/directives/edit-environment-from.html'
});

function EditEnvironmentFrom($attrs,
$filter,
$scope,
utils) {
var ctrl = this;

var canI = $filter('canI');
var humanizeKind = $filter('humanizeKind');

ctrl.$id = $scope.$id;
ctrl.setFocusClass = 'edit-environment-from-set-focus-' + ctrl.$id;

var addEntry = function(entries, entry) {
entries && entries.push(entry || {});
};

ctrl.onAddRow = function() {
addEntry(ctrl.envFromEntries);
utils.setFocusOn('.'+ ctrl.setFocusClass);
};

ctrl.deleteEntry = function(start, deleteCount) {
if(ctrl.entries && !ctrl.entries.length) {
return;
}

ctrl.envFromEntries.splice(start, deleteCount);
if(!ctrl.envFromEntries.length && ctrl.addRowLink) {
addEntry(ctrl.envFromEntries);
}

ctrl.updateEntries(ctrl.envFromEntries);
$scope.forms.editEnvironmentFrom.$setDirty();
};

ctrl.isEnvFromReadonly = function(entry) {
return ctrl.isReadonlyAny ||
entry.isReadonlyValue === true ||
((entry.secretRef || entry.configMapRef) && !entry.selectedEnvFrom) ||
_.isEmpty(ctrl.envFromSelectorOptions);
};

ctrl.groupByKind = function(object) {
return humanizeKind(object.kind);
};

ctrl.envFromObjectSelected = function(index, entry, selected) {
var newEnvFrom = {};

switch (selected.kind) {
case 'Secret':
newEnvFrom.secretRef = {
name: selected.metadata.name
};
delete ctrl.envFromEntries[index].configMapRef;
break;
case 'ConfigMap':
newEnvFrom.configMapRef = {
name: selected.metadata.name
};
delete ctrl.envFromEntries[index].secretRef;
break;
}

_.assign(ctrl.envFromEntries[index], newEnvFrom);
ctrl.updateEntries(ctrl.envFromEntries);
};

ctrl.updateEntries = function(entries) {
ctrl.entries = _.filter(_.clone(entries), function (val) {
return val.secretRef || val.configMapRef;
});
};

ctrl.updateEnvFromEntries = function(entries) {
ctrl.envFromEntries = _.clone(entries || []);

if(!ctrl.envFromEntries.length) {
addEntry(ctrl.envFromEntries);
}

_.each(ctrl.envFromEntries, function(entry) {
if(entry) {
if (entry.configMapRef) {
entry.isReadonlyValue = !canI('configmaps', 'get');
}

if (entry.secretRef) {
entry.isReadonlyValue = !canI('secrets', 'get');
}
}
});
};

var getReferenceValue = function(option) {
var referenceValue;

switch(option.kind) {
case 'ConfigMap':
referenceValue = _.find(ctrl.envFromEntries, {configMapRef: {name: option.metadata.name}});
break;
case 'Secret':
referenceValue = _.find(ctrl.envFromEntries, {secretRef: {name: option.metadata.name}});
break;
}

return referenceValue;
};

ctrl.checkEntries = function(option) {
return !!(getReferenceValue(option));
};

var findReferenceValueForEntries = function(entries, envFromSelectorOptions) {
_.each(envFromSelectorOptions, function(option) {
var referenceValue = getReferenceValue(option);

if (referenceValue) {
_.set(referenceValue, 'selectedEnvFrom', option);
}
});
};

angular.extend($scope, {
dragControlListeners: {
accept: function (sourceItemHandleScope, destSortableScope) {
return sourceItemHandleScope.itemScope.sortableScope.$id === destSortableScope.$id;
},
orderChanged: function() {
$scope.forms.editEnvironmentFrom.$setDirty();
}
}
});

ctrl.$onInit = function() {
ctrl.updateEnvFromEntries(ctrl.entries);
findReferenceValueForEntries(ctrl.envFromEntries, ctrl.envFromSelectorOptions);

if('cannotAdd' in $attrs) {
ctrl.cannotAdd = true;
}

if('cannotDelete' in $attrs) {
ctrl.cannotDeleteAny = true;
}

if('cannotSort' in $attrs) {
ctrl.cannotSort = true;
}

if('isReadonly' in $attrs) {
ctrl.isReadonlyAny = true;
}

if('showHeader' in $attrs) {
ctrl.showHeader = true;
}

if(ctrl.envFromEntries && !ctrl.envFromEntries.length) {
addEntry(ctrl.envFromEntries);
}
};

ctrl.$onChanges = function(changes) {
if(changes.entries) {
ctrl.updateEnvFromEntries(changes.entries.currentValue);
}

if(changes.envFromSelectorOptions) {
findReferenceValueForEntries(ctrl.envFromEntries, changes.envFromSelectorOptions.currentValue);
}
};
}
})();

10 changes: 8 additions & 2 deletions app/scripts/services/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ angular.module("openshiftConsole")
var containers = getContainers(object);
_.each(containers, function(container) {
container.env = container.env || [];
container.envFrom = container.envFrom || [];
});
},

Expand Down Expand Up @@ -50,7 +51,7 @@ angular.module("openshiftConsole")
return false;
}

var i, leftEnv, rightEnv;
var i, leftEnv, rightEnv, leftEnvFrom, rightEnvFrom;
for (i = 0; i < leftContainers.length; i++) {
// If a container name has changed, consider it a conflict.
if (leftContainers[i].name !== rightContainers[i].name) {
Expand All @@ -60,7 +61,11 @@ angular.module("openshiftConsole")
// Check if any of the variable names or values are different.
leftEnv = leftContainers[i].env || [];
rightEnv = rightContainers[i].env || [];
if (!_.isEqual(leftEnv, rightEnv)) {

leftEnvFrom = leftContainers[i].envFrom || [];
rightEnvFrom = rightContainers[i].envFrom || [];

if (!_.isEqual(leftEnv, rightEnv) || !_.isEqual(leftEnvFrom, rightEnvFrom)) {
return false;
}
}
Expand All @@ -78,6 +83,7 @@ angular.module("openshiftConsole")
var targetContainers = getContainers(copy);
for (i = 0; i < targetContainers.length; i++) {
targetContainers[i].env = _.get(sourceContainers, [i, 'env'], []);
targetContainers[i].envFrom = _.get(sourceContainers, [i, 'envFrom'], []);
}

return copy;
Expand Down
94 changes: 94 additions & 0 deletions app/views/directives/edit-environment-from.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<ng-form name="forms.editEnvironmentFrom" novalidate>
<div
ng-if="$ctrl.showHeader"
class="key-value-editor-entry key-value-editor-entry-header">
<div class="form-group key-value-editor-header value-header">
<div class="input-group">
<span class="help-block">{{$ctrl.selectorPlaceholder}}</span>
</div>
</div>
</div>

<div ng-model="$ctrl.entries" class="key-value-editor" as-sortable="dragControlListeners">
<div
class="key-value-editor-entry"
ng-class-odd="'odd'"
ng-class-even="'even'"
ng-repeat="entry in $ctrl.envFromEntries"
as-sortable-item>

<div
class="form-group key-value-editor-input"
ng-class="{ 'has-error': (forms.editEnvironmentFrom[uniqueForValue(unique, $index)].$invalid && forms.editEnvironmentFrom[uniqueForValue(unique, $index)].$touched) }">
<div ng-if="$ctrl.isEnvFromReadonly(entry)" class="faux-input-group">
<div class="faux-form-control readonly">
Set to values in {{entry.selectedEnvFrom.kind | humanizeKind : true | lowercase}}
<span
ng-if="!('configmaps' | canI : 'get') || !('secrets' | canI : 'get')">
{{entry.configMapRef.name || entry.secretRef.name}}
</span>
<a
ng-if="'configmaps' | canI : 'get'"
ng-href="{{entry.selectedEnvFrom | navigateResourceURL}}">
{{entry.configMapRef.name || entry.secretRef.name}}
</a>
</div>
</div>

<div ng-if="!$ctrl.isEnvFromReadonly(entry)">
<div class="ui-select">
<ui-select ng-model="entry.selectedEnvFrom"
ng-required="entry.selectedEnvFrom"
on-select="$ctrl.envFromObjectSelected($index, entry, $select.selected)"
ng-class="{'{{$ctrl.setFocusClass}}' : $last}">
<ui-select-match placeholder="Select a resource">
<span>
{{$select.selected.metadata.name}}
<small class="text-muted">&ndash; {{$select.selected.kind | humanizeKind : true}}</small>
</span>
</ui-select-match>
<ui-select-choices
ui-disable-choice="$ctrl.checkEntries(source)"
repeat="source in $ctrl.envFromSelectorOptions | filter : { metadata: { name: $select.search } } track by (source | uid)"
group-by="$ctrl.groupByKind">
<span ng-bind-html="source.metadata.name | highlight : $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>

<div>
<span
ng-if="(!$ctrl.cannotSort) && ($ctrl.entries.length > 1)"
class="fa fa-bars sort-row"
role="button"
aria-label="Move row"
aria-grabbed="false"
as-sortable-item-handle></span>
<a
href=""
class="pficon pficon-close delete-row as-sortable-item-delete"
role="button"
aria-label="Delete row"
ng-hide="$ctrl.cannotDeleteAny"
ng-click="$ctrl.deleteEntry($index, 1)"></a>
<a
ng-href="{{entry.selectedEnvFrom | navigateResourceURL}}"
class="pficon"
ng-show="entry.selectedEnvFrom"
ng-click="$ctrl.viewDetail(entry)">View {{entry.selectedEnvFrom.kind | humanizeKind : true}}</a>
</div>
</div>
</div>

<div class="key-value-editor-entry form-group" ng-if="(!$ctrl.cannotAdd)">
<a
href=""
class="add-row-link"
role="button"
aria-label="Add row"
ng-click="$ctrl.onAddRow()">{{ $ctrl.addRowLink }}</a>
</div>
</div>
</ng-form>

17 changes: 17 additions & 0 deletions app/views/directives/edit-environment-variables.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<confirm-on-exit ng-if="$ctrl.canIUpdate && !$ctrl.ngReadonly" dirty="$ctrl.form.$dirty"></confirm-on-exit>
<div ng-repeat="container in $ctrl.containers">
<h3>Container {{container.name}}</h3>

<h4>Variables</h4>
<div ng-if="!$ctrl.canIUpdate || $ctrl.ngReadonly">
<span ng-if="!container.env.length">
No environment variables set in the {{$ctrl.apiObject.kind | humanizeKind}}
Expand Down Expand Up @@ -32,6 +34,21 @@ <h3>Container {{container.name}}</h3>
add-row-with-selectors-link="Add Environment Variable Using a Config Map or Secret"
show-header>
</key-value-editor>

<h4>
Environment From
<span class="pficon pficon-info"
aria-hidden="true"
data-toggle="tooltip"
data-original-title="Environment From lets you add all key value pairs from a config map or secret."></span>
</h4>
<edit-environment-from
entries="container.envFrom"
selector-placeholder="Secret/Config Map"
env-from-selector-options="$ctrl.valueFromObjects"
add-row-link="Add ALL Values from a Resource"
show-header>
</edit-environment-from>
</div>
<button
class="btn btn-default"
Expand Down
Loading

0 comments on commit 71ac457

Please sign in to comment.