Commit 79e31fda by Jessica Forrester Committed by GitHub

Merge pull request #58 from jeff-phillips-18/bind

Add common components for binding
parents bb3f5eab 42d9adc3
.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