Commit 42d9adc3 by Jeffrey Phillips

Add common directives for binding

Adds bindApplicationForm, bindServiceForm, and bindResults

Adds common filters for statusCondition, and isServcieInstanceReady
(these will need to be removed from console).
parent bb3f5eab
.bind-form {
h3 {
margin-top: 0;
}
.application-select {
margin-top: 10px;
padding-left: 20px;
}
.bind-description {
padding-left: 20px;
}
.bind-choice {
margin-top: 10px;
&:first-of-type {
margin-top: 0;
}
}
.help-block {
&.service-instance-name {
display: inline-block;
margin-top: 0;
}
}
.radio label[disabled] {
cursor: not-allowed;
}
}
.bind-info {
margin-bottom: 20px;
margin-top: 30px;
}
.bind-status {
display: flex;
font-size: 16px;
margin-top: 0;
.bind-message {
flex: 1;
line-height: 1.4;
margin-top: 0;
padding-left: 10px;
}
.pficon {
margin-top: 3px;
}
&.show-progress {
display: block;
.bind-message {
padding-left: 0;
}
}
.spinner.spinner-sm {
height: 16px;
margin-right: 0;
margin-top: 3px;
width: 16px;
}
}
.bind-pending-message {
margin-top: 15px;
&.progress-inline {
margin-top: 0;
}
}
// origin-web-common sans external dependency variables
@import "_animations.less";
@import "_bind-service.less";
@import "_core.less";
@import "_forms.less";
@import "_guided-tour.less";
......
......@@ -18,6 +18,65 @@
transform: translateX(150px);
}
}
.bind-form h3 {
margin-top: 0;
}
.bind-form .application-select {
margin-top: 10px;
padding-left: 20px;
}
.bind-form .bind-description {
padding-left: 20px;
}
.bind-form .bind-choice {
margin-top: 10px;
}
.bind-form .bind-choice:first-of-type {
margin-top: 0;
}
.bind-form .help-block.service-instance-name {
display: inline-block;
margin-top: 0;
}
.bind-form .radio label[disabled] {
cursor: not-allowed;
}
.bind-info {
margin-bottom: 20px;
margin-top: 30px;
}
.bind-status {
display: flex;
font-size: 16px;
margin-top: 0;
}
.bind-status .bind-message {
flex: 1;
line-height: 1.4;
margin-top: 0;
padding-left: 10px;
}
.bind-status .pficon {
margin-top: 3px;
}
.bind-status.show-progress {
display: block;
}
.bind-status.show-progress .bind-message {
padding-left: 0;
}
.bind-status .spinner.spinner-sm {
height: 16px;
margin-right: 0;
margin-top: 3px;
width: 16px;
}
.bind-pending-message {
margin-top: 15px;
}
.bind-pending-message.progress-inline {
margin-top: 0;
}
.delete-resource-modal {
background-color: #f1f1f1;
}
......
angular.module('openshiftCommonUI').run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('src/components/binding/bindApplicationForm.html',
"<div class=\"bind-form\">\n" +
" <form>\n" +
" <div class=\"form-group\">\n" +
" <label>\n" +
" <h3>Bind a service to <strong>{{ctrl.applicationName}}</strong></h3>\n" +
" </label>\n" +
" <span class=\"help-block\">\n" +
" Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.\n" +
" </span>\n" +
" </div>\n" +
" </form>\n" +
"\n" +
" <form name=\"ctrl.formName\">\n" +
" <fieldset>\n" +
" <div class=\"radio\">\n" +
" <label ng-if=\"ctrl.allowNoBinding\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"\">\n" +
" Do not bind at this time.\n" +
" </label>\n" +
" <div class=\"bind-description\">\n" +
" <span class=\"help-block service-instance-name\">\n" +
" You can create the binding later from your project.\n" +
" </span>\n" +
" </div>\n" +
" <div ng-repeat=\"serviceInstance in ctrl.serviceInstances\">\n" +
" <label>\n" +
" <input type=\"radio\" ng-model=\"ctrl.serviceToBind\" value=\"{{serviceInstance.metadata.name}}\">\n" +
" {{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}\n" +
" </label>\n" +
" <div class=\"bind-description\">\n" +
" <span class=\"pficon pficon-info\"\n" +
" ng-if=\"!(serviceInstance | isServiceInstanceReady)\"\n" +
" data-content=\"This service is not yet ready. If you bind to it, then the binding will be pending until the service is ready.\"\n" +
" data-toggle=\"popover\"\n" +
" data-trigger=\"hover\">\n" +
" </span>\n" +
" <span class=\"help-block service-instance-name\">\n" +
" {{serviceInstance.metadata.name}}\n" +
" </span>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n" +
" </fieldset>\n" +
" </form>\n" +
"</div>\n"
);
$templateCache.put('src/components/binding/bindResults.html',
"<div ng-if=\"!ctrl.error\">\n" +
" <div ng-if=\"!(ctrl.binding | isBindingReady)\" class=\"bind-status\" ng-class=\"{'text-center': !ctrl.progressInline, 'show-progress': !ctrl.progressInline}\">\n" +
" <div class=\"spinner\" ng-class=\"{'spinner-sm': ctrl.progressInline, 'spinner-inline': ctrl.progressInline, 'spinner-lg': !ctrl.progressInline}\" aria-hidden=\"true\"></div>\n" +
" <h3 class=\"bind-message\">\n" +
" <span class=\"sr-only\">Pending</span>\n" +
" <div class=\"bind-pending-message\" ng-class=\"{'progress-inline': ctrl.progressInline}\">The binding was created but is not ready yet.</div>\n" +
" </h3>\n" +
" </div>\n" +
" <div ng-if=\"(ctrl.binding | isBindingReady)\">\n" +
" <div class=\"bind-status\">\n" +
" <span class=\"pficon pficon-ok\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">Success</span>\n" +
" <h3 class=\"bind-message\">\n" +
" <strong>{{ctrl.serviceToBind}}</strong>\n" +
" <span>&nbsp;has been bound</span>\n" +
" <span ng-if=\"ctrl.applicationToBind\">&nbsp;to <strong>{{ctrl.applicationToBind}}</strong> successfully</span>\n" +
" </h3>\n" +
" </div>\n" +
" <div class=\"sub-title\">\n" +
" The binding operation created the secret\n" +
" <a ng-if=\"ctrl.secretHref && 'secrets' | canI : 'list'\"\n" +
" ng-href=\"{{ctrl.secretHref}}\">{{ctrl.generatedSecretName}}</a>\n" +
" <span ng-if=\"!ctrl.secretHref || !('secrets' | canI : 'list')\">{{ctrl.generatedSecretName}}</span>\n" +
" that you may need to reference in your application.\n" +
" <span ng-if=\"ctrl.showPodPresets\">Its data will be available to your application as environment variables.</span>\n" +
" </div>\n" +
" <div class=\"alert alert-info bind-info\">\n" +
" <span class=\"pficon pficon-info\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">Info</span>\n" +
" The binding secret will only be available to new pods. You will need to redeploy your application.\n" +
" </div>\n" +
" </div>\n" +
"</div>\n" +
"<div ng-if=\"ctrl.error\">\n" +
" <div class=\"bind-status\">\n" +
" <span class=\"pficon pficon-error-circle-o text-danger\" aria-hidden=\"true\"></span>\n" +
" <span class=\"sr-only\">Error</span>\n" +
" <h3 class=\"bind-message\">\n" +
" <span>Binding Failed</span>\n" +
" </h3>\n" +
" </div>\n" +
" <div class=\"sub-title\">\n" +
" <span ng-if=\"ctrl.error.data.message\">\n" +
" {{ctrl.error.data.message | upperFirst}}\n" +
" </span>\n" +
" <span ng-if=\"!ctrl.error.data.message\">\n" +
" An error occurred creating the binding.\n" +
" </span>\n" +
" </div>\n" +
"</div>\n"
);
$templateCache.put('src/components/binding/bindServiceForm.html',
"<div class=\"bind-form\">\n" +
" <form>\n" +
" <div class=\"form-group\">\n" +
" <label>\n" +
" <h3>Bind <strong>{{ctrl.serviceClass.osbMetadata.displayName || ctrl.serviceClassName}}</strong> to an existing application</strong></h3>\n" +
" </label>\n" +
" <span class=\"help-block\">Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.</span>\n" +
" </div>\n" +
" </form>\n" +
"\n" +
" <form name=\"ctrl.formName\" class=\"mar-bottom-lg\">\n" +
" <fieldset>\n" +
" <div class=\"radio\">\n" +
" <label class=\"bind-choice\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.shouldBindToApp\" value=\"true\">\n" +
" Bind to an application\n" +
" </label>\n" +
" <div class=\"application-select\">\n" +
" <ui-select ng-model=\"ctrl.appToBind\"\n" +
" ng-disabled=\"ctrl.shouldBindToApp !== 'true'\"\n" +
" ng-required=\"ctrl.shouldBindToApp === 'true'\">\n" +
" <ui-select-match placeholder=\"Select an application\">\n" +
" <span>\n" +
" {{$select.selected.metadata.name}}\n" +
" <small class=\"text-muted\">&ndash; {{$select.selected.kind | humanizeKind : true}}</small>\n" +
" </span>\n" +
" </ui-select-match>\n" +
" <ui-select-choices\n" +
" repeat=\"application in (ctrl.applications) | filter : { metadata: { name: $select.search } } track by (application | uid)\"\n" +
" group-by=\"ctrl.groupByKind\">\n" +
" <span ng-bind-html=\"application.metadata.name | highlight : $select.search\"></span>\n" +
" </ui-select-choices>\n" +
" </ui-select>\n" +
" </div>\n" +
" <label class=\"bind-choice\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.shouldBindToApp\" value=\"false\">\n" +
" Create a secret in my project\n" +
" </label>\n" +
" <div class=\"help-block bind-description\">\n" +
" You can reference this secret later from any application either as environment variables or configuration files mounted as volumes.\n" +
" </div>\n" +
" <label ng-if=\"ctrl.allowNoBinding\" class=\"bind-choice\">\n" +
" <input type=\"radio\" ng-model=\"ctrl.shouldBindToApp\" value=\"none\">\n" +
" Do not bind at this time\n" +
" </label>\n" +
" <div ng-if=\"ctrl.allowNoBinding\" class=\"help-block bind-description\">\n" +
" You can create the binding later from your project.\n" +
" </div>\n" +
" </div>\n" +
" </fieldset>\n" +
" </form>\n" +
"</div>\n"
);
$templateCache.put('src/components/create-project/createProject.html',
"<form name=\"createProjectForm\" novalidate>\n" +
" <fieldset ng-disabled=\"disableInputs\">\n" +
......
<div class="bind-form">
<form>
<div class="form-group">
<label>
<h3>Bind a service to <strong>{{ctrl.applicationName}}</strong></h3>
</label>
<span class="help-block">
Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.
</span>
</div>
</form>
<form name="ctrl.formName">
<fieldset>
<div class="radio">
<label ng-if="ctrl.allowNoBinding">
<input type="radio" ng-model="ctrl.serviceToBind" value="">
Do not bind at this time.
</label>
<div class="bind-description">
<span class="help-block service-instance-name">
You can create the binding later from your project.
</span>
</div>
<div ng-repeat="serviceInstance in ctrl.serviceInstances">
<label>
<input type="radio" ng-model="ctrl.serviceToBind" value="{{serviceInstance.metadata.name}}">
{{ctrl.serviceClasses[serviceInstance.spec.serviceClassName].osbMetadata.displayName || serviceInstance.spec.serviceClassName}}
</label>
<div class="bind-description">
<span class="pficon pficon-info"
ng-if="!(serviceInstance | isServiceInstanceReady)"
data-content="This service is not yet ready. If you bind to it, then the binding will be pending until the service is ready."
data-toggle="popover"
data-trigger="hover">
</span>
<span class="help-block service-instance-name">
{{serviceInstance.metadata.name}}
</span>
</div>
</div>
</div>
</fieldset>
</form>
</div>
'use strict';
angular.module('openshiftCommonUI').component('bindApplicationForm', {
controllerAs: 'ctrl',
bindings: {
allowNoBinding: '<?',
createBinding: '=',
applicationName: '=',
formName: '=',
serviceClasses: '<',
serviceInstances: '<',
serviceToBind: '='
},
templateUrl: 'src/components/binding/bindApplicationForm.html',
controller: function () {
var ctrl = this;
}
});
<div ng-if="!ctrl.error">
<div ng-if="!(ctrl.binding | isBindingReady)" class="bind-status" ng-class="{'text-center': !ctrl.progressInline, 'show-progress': !ctrl.progressInline}">
<div class="spinner" ng-class="{'spinner-sm': ctrl.progressInline, 'spinner-inline': ctrl.progressInline, 'spinner-lg': !ctrl.progressInline}" aria-hidden="true"></div>
<h3 class="bind-message">
<span class="sr-only">Pending</span>
<div class="bind-pending-message" ng-class="{'progress-inline': ctrl.progressInline}">The binding was created but is not ready yet.</div>
</h3>
</div>
<div ng-if="(ctrl.binding | isBindingReady)">
<div class="bind-status">
<span class="pficon pficon-ok" aria-hidden="true"></span>
<span class="sr-only">Success</span>
<h3 class="bind-message">
<strong>{{ctrl.serviceToBind}}</strong>
<span>&nbsp;has been bound</span>
<span ng-if="ctrl.applicationToBind">&nbsp;to <strong>{{ctrl.applicationToBind}}</strong> successfully</span>
</h3>
</div>
<div class="sub-title">
The binding operation created the secret
<a ng-if="ctrl.secretHref && 'secrets' | canI : 'list'"
ng-href="{{ctrl.secretHref}}">{{ctrl.generatedSecretName}}</a>
<span ng-if="!ctrl.secretHref || !('secrets' | canI : 'list')">{{ctrl.generatedSecretName}}</span>
that you may need to reference in your application.
<span ng-if="ctrl.showPodPresets">Its data will be available to your application as environment variables.</span>
</div>
<div class="alert alert-info bind-info">
<span class="pficon pficon-info" aria-hidden="true"></span>
<span class="sr-only">Info</span>
The binding secret will only be available to new pods. You will need to redeploy your application.
</div>
</div>
</div>
<div ng-if="ctrl.error">
<div class="bind-status">
<span class="pficon pficon-error-circle-o text-danger" aria-hidden="true"></span>
<span class="sr-only">Error</span>
<h3 class="bind-message">
<span>Binding Failed</span>
</h3>
</div>
<div class="sub-title">
<span ng-if="ctrl.error.data.message">
{{ctrl.error.data.message | upperFirst}}
</span>
<span ng-if="!ctrl.error.data.message">
An error occurred creating the binding.
</span>
</div>
</div>
'use strict';
angular.module('openshiftCommonUI').component('bindResults', {
controllerAs: 'ctrl',
bindings: {
error: '<',
binding: '<',
progressInline: '@',
serviceToBind: '<',
applicationToBind: '<',
generatedSecretName: '<',
showPodPresets: '<',
secretHref: '<'
},
templateUrl: 'src/components/binding/bindResults.html',
controller: function() {
var ctrl = this;
ctrl.$onInit = function () {
ctrl.progressInline = ctrl.progressInline === 'true';
};
ctrl.$onChanges = function(onChangesObj) {
if (onChangesObj.progressInline) {
ctrl.progressInline = ctrl.progressInline === 'true';
}
}
}
});
<div class="bind-form">
<form>
<div class="form-group">
<label>
<h3>Bind <strong>{{ctrl.serviceClass.osbMetadata.displayName || ctrl.serviceClassName}}</strong> to an existing application</strong></h3>
</label>
<span class="help-block">Binding to a provisioned service will create a secret containing the information necessary for your application to use the service.</span>
</div>
</form>
<form name="ctrl.formName" class="mar-bottom-lg">
<fieldset>
<div class="radio">
<label class="bind-choice">
<input type="radio" ng-model="ctrl.shouldBindToApp" value="true">
Bind to an application
</label>
<div class="application-select">
<ui-select ng-model="ctrl.appToBind"
ng-disabled="ctrl.shouldBindToApp !== 'true'"
ng-required="ctrl.shouldBindToApp === 'true'">
<ui-select-match placeholder="Select an application">
<span>
{{$select.selected.metadata.name}}
<small class="text-muted">&ndash; {{$select.selected.kind | humanizeKind : true}}</small>
</span>
</ui-select-match>
<ui-select-choices
repeat="application in (ctrl.applications) | filter : { metadata: { name: $select.search } } track by (application | uid)"
group-by="ctrl.groupByKind">
<span ng-bind-html="application.metadata.name | highlight : $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
<label class="bind-choice">
<input type="radio" ng-model="ctrl.shouldBindToApp" value="false">
Create a secret in my project
</label>
<div class="help-block bind-description">
You can reference this secret later from any application either as environment variables or configuration files mounted as volumes.
</div>
<label ng-if="ctrl.allowNoBinding" class="bind-choice">
<input type="radio" ng-model="ctrl.shouldBindToApp" value="none">
Do not bind at this time
</label>
<div ng-if="ctrl.allowNoBinding" class="help-block bind-description">
You can create the binding later from your project.
</div>
</div>
</fieldset>
</form>
</div>
'use strict';
angular.module('openshiftCommonUI').component('bindServiceForm', {
controllerAs: 'ctrl',
bindings: {
serviceClass: '<',
serviceClassName: '<',
formName: '=',
applications: '<',
appToBind: '=',
createBinding: '=?',
allowNoBinding: '<?',
shouldBindToApp: '=',
groupByKind: '<'
},
templateUrl: 'src/components/binding/bindServiceForm.html',
controller: function () {
var ctrl = this;
}
});
......@@ -114,4 +114,23 @@ angular.module('openshiftCommonUI')
return humanized.toLowerCase();
};
})
// gets the status condition that matches provided type
// statusCondition(object, 'Ready')
.filter('statusCondition', function() {
return function(apiObject, type) {
if (!apiObject) {
return null;
}
return _.find(_.get(apiObject, 'status.conditions'), {type: type});
};
})
.filter('isServiceInstanceReady', function(statusConditionFilter) {
return function(apiObject) {
return _.get(statusConditionFilter(apiObject, 'Ready'), 'status') === 'True';
};
})
.filter('isBindingReady', function(isServiceInstanceReadyFilter) {
return isServiceInstanceReadyFilter;
});
.bind-form {
h3 {
margin-top: 0;
}
.application-select {
margin-top: 10px;
padding-left: 20px;
}
.bind-description {
padding-left: 20px;
}
.bind-choice {
margin-top: 10px;
&:first-of-type {
margin-top: 0;
}
}
.help-block {
&.service-instance-name {
display: inline-block;
margin-top: 0;
}
}
.radio label[disabled] {
cursor: not-allowed;
}
}
.bind-info {
margin-bottom: 20px;
margin-top: 30px;
}
.bind-status {
display: flex;
font-size: 16px;
margin-top: 0;
.bind-message {
flex: 1;
line-height: 1.4;
margin-top: 0;
padding-left: 10px;
}
.pficon {
margin-top: 3px;
}
&.show-progress {
display: block;
.bind-message {
padding-left: 0;
}
}
.spinner.spinner-sm {
height: 16px;
margin-right: 0;
margin-top: 3px;
width: 16px;
}
}
.bind-pending-message {
margin-top: 15px;
&.progress-inline {
margin-top: 0;
}
}
// origin-web-common sans external dependency variables
@import "_animations.less";
@import "_bind-service.less";
@import "_core.less";
@import "_forms.less";
@import "_guided-tour.less";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment