Skip to content

Commit 73c7420

Browse files
author
OpenShift Bot
authored
Merge pull request #1966 from jeff-phillips-18/browse
Merged by openshift-bot
2 parents 2d2e297 + 197c465 commit 73c7420

15 files changed

+450
-54
lines changed

app/scripts/controllers/landingPage.js

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ angular.module('openshiftConsole')
8585
_.set($scope, 'ordering.panelName', 'fromFile');
8686
};
8787

88+
$scope.fromProjectSelected = function() {
89+
_.set($scope, 'ordering.panelName', 'fromProject');
90+
};
91+
8892
AuthService.withUser().then(function() {
8993
var includeTemplates = !_.get(Constants, 'ENABLE_TECH_PREVIEW_FEATURE.template_service_broker');
9094
Catalog.getCatalogItems(includeTemplates).then(_.spread(function(items, errorMessage) {

app/scripts/directives/processTemplate.js

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
bindings: {
2323
template: '<',
2424
project: '<',
25+
onProjectSelected: '<',
26+
availableProjects: '<',
2527
prefillParameters: '<',
2628
isDialog: '<'
2729
},

app/scripts/directives/processTemplateDialog.js

+165-3
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,46 @@
44
angular.module('openshiftConsole').component('processTemplateDialog', {
55
controller: [
66
'$scope',
7+
'$filter',
8+
'Catalog',
79
'DataService',
10+
'KeywordService',
11+
'NotificationsService',
12+
'ProjectsService',
13+
'RecentlyViewedProjectsService',
814
ProcessTemplateDialog
915
],
1016
controllerAs: '$ctrl',
1117
bindings: {
1218
template: '<',
19+
project: '<',
20+
useProjectTemplate: '<',
1321
onDialogClosed: '&'
1422
},
1523
templateUrl: 'views/directives/process-template-dialog.html'
1624
});
1725

18-
function ProcessTemplateDialog($scope, DataService) {
26+
function ProcessTemplateDialog($scope,
27+
$filter,
28+
Catalog,
29+
DataService,
30+
KeywordService,
31+
NotificationsService,
32+
ProjectsService,
33+
RecentlyViewedProjectsService) {
1934
var ctrl = this;
2035
var validityWatcher;
2136

37+
ctrl.selectStep = {
38+
id: 'projectTemplates',
39+
label: 'Selection',
40+
view: 'views/directives/process-template-dialog/process-template-select.html',
41+
hidden: ctrl.useProjectTemplate !== true,
42+
allowed: true,
43+
valid: false,
44+
onShow: showSelect
45+
};
46+
2247
ctrl.configStep = {
2348
id: 'configuration',
2449
label: 'Configuration',
@@ -43,6 +68,38 @@
4368

4469
ctrl.$onInit = function() {
4570
ctrl.loginBaseUrl = DataService.openshiftAPIBaseUrl();
71+
ctrl.preSelectedProject = ctrl.selectedProject = ctrl.project;
72+
listProjects();
73+
74+
ctrl.projectEmptyState = {
75+
icon: 'pficon pficon-info',
76+
title: 'No Project Selected',
77+
info: 'Please select a project from the dropdown to load Templates from that project.'
78+
};
79+
80+
ctrl.templatesEmptyState = {
81+
icon: 'pficon pficon-info',
82+
title: 'No Templates',
83+
info: 'The selected project has no templates available to import.'
84+
};
85+
86+
ctrl.filterConfig = {
87+
fields: [
88+
{
89+
id: 'keyword',
90+
title: 'Keyword',
91+
placeholder: 'Filter by Keyword',
92+
filterType: 'text'
93+
}
94+
],
95+
inlineResults: true,
96+
showTotalCountResults: true,
97+
itemsLabel: 'Item',
98+
itemsLabelPlural: 'Items',
99+
resultsCount: 0,
100+
appliedFilters: [],
101+
onFilterChange: filterChange
102+
};
46103
};
47104

48105
ctrl.$onChanges = function(changes) {
@@ -52,6 +109,9 @@
52109
ctrl.iconClass = getIconClass();
53110
}
54111
}
112+
if (changes.useProjectTemplate) {
113+
initializeSteps();
114+
}
55115
};
56116

57117
$scope.$on('templateInstantiated', function(event, message) {
@@ -85,13 +145,49 @@
85145
}
86146
};
87147

148+
ctrl.onProjectSelected = function(project) {
149+
ctrl.selectedProject = project;
150+
ctrl.configStep.valid = $scope.$ctrl.form.$valid && ctrl.selectedProject;
151+
};
152+
153+
ctrl.templateSelected = function(template) {
154+
ctrl.selectedTemplate = template;
155+
ctrl.template = _.get(template, 'resource');
156+
ctrl.selectStep.valid = !!template;
157+
};
158+
159+
ctrl.templateProjectChange = function () {
160+
ctrl.templateProjectName = _.get(ctrl.templateProject, 'metadata.name');
161+
162+
// Get the templates for the selected project
163+
ctrl.catalogItems = {};
164+
ctrl.templateSelected();
165+
166+
Catalog.getProjectCatalogItems(ctrl.templateProjectName, false, true).then( _.spread(function(catalogServiceItems, errorMessage) {
167+
ctrl.catalogItems = catalogServiceItems;
168+
ctrl.totalCount = ctrl.catalogItems.length;
169+
filterItems();
170+
171+
if (errorMessage) {
172+
NotificationsService.addNotification(
173+
{
174+
type: "error",
175+
message: errorMessage
176+
}
177+
);
178+
}
179+
}));
180+
};
181+
88182
function getIconClass() {
89183
var icon = _.get(ctrl, 'template.metadata.annotations.iconClass', 'fa fa-clone');
90184
return (icon.indexOf('icon-') !== -1) ? 'font-icon ' + icon : icon;
91185
}
92186

93187
function initializeSteps() {
94-
ctrl.steps = [ctrl.configStep, ctrl.resultsStep];
188+
if (!ctrl.steps) {
189+
ctrl.steps = [ctrl.selectStep, ctrl.configStep, ctrl.resultsStep];
190+
}
95191
}
96192

97193
function clearValidityWatcher() {
@@ -101,19 +197,30 @@
101197
}
102198
}
103199

200+
function showSelect() {
201+
ctrl.selectStep.selected = true;
202+
ctrl.configStep.selected = false;
203+
ctrl.resultsStep.selected = false;
204+
ctrl.nextTitle = "Next >";
205+
clearValidityWatcher();
206+
listProjects();
207+
}
208+
104209
function showConfig() {
210+
ctrl.selectStep.selected = false;
105211
ctrl.configStep.selected = true;
106212
ctrl.resultsStep.selected = false;
107213
ctrl.nextTitle = "Create";
108214
ctrl.resultsStep.allowed = ctrl.configStep.valid;
109215

110216
validityWatcher = $scope.$watch("$ctrl.form.$valid", function(isValid) {
111-
ctrl.configStep.valid = isValid;
217+
ctrl.configStep.valid = isValid && ctrl.selectedProject;
112218
ctrl.resultsStep.allowed = isValid;
113219
});
114220
}
115221

116222
function showResults() {
223+
ctrl.selectStep.selected = false;
117224
ctrl.configStep.selected = false;
118225
ctrl.resultsStep.selected = true;
119226
ctrl.nextTitle = "Close";
@@ -124,5 +231,60 @@
124231
function instantiateTemplate() {
125232
$scope.$broadcast('instantiateTemplate');
126233
}
234+
235+
function filterForKeywords(searchText, items) {
236+
return KeywordService.filterForKeywords(items, ['name', 'tags'], KeywordService.generateKeywords(searchText));
237+
}
238+
239+
function filterChange(filters) {
240+
ctrl.filterConfig.appliedFilters = filters;
241+
filterItems();
242+
}
243+
244+
function filterItems() {
245+
ctrl.filteredItems = ctrl.catalogItems;
246+
if (ctrl.filterConfig.appliedFilters && ctrl.filterConfig.appliedFilters.length > 0) {
247+
_.each(ctrl.filterConfig.appliedFilters, function(filter) {
248+
ctrl.filteredItems = filterForKeywords(filter.value, ctrl.filteredItems);
249+
});
250+
}
251+
252+
// Deselect the currently selected template if it was filtered out
253+
if (!_.includes(ctrl.filteredItems, ctrl.selectedTemplate)) {
254+
ctrl.templateSelected();
255+
}
256+
257+
updateFilterControls();
258+
}
259+
260+
function updateFilterControls() {
261+
ctrl.filterConfig.resultsCount = ctrl.filteredItems.length;
262+
263+
if (ctrl.totalCount <= 1) {
264+
$('.filter-pf.filter-fields input').attr('disabled', '');
265+
} else {
266+
$('.filter-pf.filter-fields input').removeAttr("disabled");
267+
}
268+
}
269+
270+
var updateProjects = function() {
271+
var filteredProjects = _.reject(ctrl.unfilteredProjects, 'metadata.deletionTimestamp');
272+
var projects = _.sortBy(filteredProjects, $filter('displayName'));
273+
ctrl.searchEnabled = !_.isEmpty(filteredProjects);
274+
275+
ctrl.templateProjects = RecentlyViewedProjectsService.orderByMostRecentlyViewed(projects);
276+
};
277+
278+
function listProjects() {
279+
if (!ctrl.unfilteredProjects) {
280+
ProjectsService.list().then(function(projectData) {
281+
ctrl.unfilteredProjects = _.toArray(projectData.by("metadata.name"));
282+
}, function() {
283+
ctrl.unfilteredProjects = [];
284+
}).finally(function() {
285+
updateProjects();
286+
});
287+
}
288+
}
127289
}
128290
})();

app/styles/_core.less

+48
Original file line numberDiff line numberDiff line change
@@ -1246,3 +1246,51 @@ pre.clipped {
12461246
width: 30px;
12471247
}
12481248
}
1249+
1250+
.order-service-config {
1251+
.order-services-filter {
1252+
margin-left: 0;
1253+
}
1254+
.blank-slate-pf {
1255+
margin-bottom: 0;
1256+
padding-bottom: 0;
1257+
}
1258+
.select-project-for-template {
1259+
border-bottom: solid 1px @color-pf-black-300;
1260+
padding-bottom: 10px;
1261+
1262+
> h2 {
1263+
margin-bottom: 20px;
1264+
margin-top: 0;
1265+
}
1266+
.ui-select-container {
1267+
display: inline-block;
1268+
width: 275px;
1269+
}
1270+
}
1271+
.services-item {
1272+
&.show-selection {
1273+
// Clear focus settings, keep before active settings
1274+
&:focus {
1275+
color: @text-color;
1276+
.services-item-icon:after {
1277+
border: none;
1278+
}
1279+
1280+
.services-item-name {
1281+
color: @text-color;
1282+
}
1283+
}
1284+
&.active {
1285+
color: @link-hover-color;
1286+
.services-item-icon:after {
1287+
border: 2px solid @link-color;
1288+
}
1289+
.services-item-name {
1290+
color: @link-hover-color;
1291+
}
1292+
}
1293+
}
1294+
}
1295+
}
1296+

app/styles/_overlay-forms.less

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
.order-service-config-single-column {
22
width: 100%;
3+
@media (min-width: 768px) {
4+
padding-left: 0;
5+
}
36
}
47

58
.wizard-pf-main {

app/views/directives/header/project-header.html

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<li ng-if-start="catalogLandingPageEnabled" role="menuitem"><a href="/">Browse Catalog</a></li>
3939
<li role="menuitem"><a href="" ng-click="showOrderingPanel('deployImage')">Deploy Image</a></li>
4040
<li ng-if-end role="menuitem"><a href="" ng-click="showOrderingPanel('fromFile')">Import YAML / JSON</a></li>
41+
<li ng-if-end role="menuitem"><a href="" ng-click="showOrderingPanel('fromProject')">Select from Project</a></li>
4142
</ul>
4243
</div>
4344
<div row
@@ -51,4 +52,5 @@
5152
<overlay-panel show-panel="ordering.panelName" show-close="true" handle-close="closeOrderingPanel">
5253
<deploy-image-dialog ng-if="ordering.panelName === 'deployImage'" project="project" context="context" on-dialog-closed="closeOrderingPanel"></deploy-image-dialog>
5354
<from-file-dialog ng-if="ordering.panelName === 'fromFile'" project="project" context="context" on-dialog-closed="closeOrderingPanel"></from-file-dialog>
55+
<process-template-dialog ng-if="ordering.panelName === 'fromProject'" project="project" use-project-template="true" on-dialog-closed="closeOrderingPanel"></process-template-dialog>
5456
</overlay-panel>

app/views/directives/process-template-dialog.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<pf-wizard
33
hide-header="true"
44
hide-sidebar="true"
5-
hide-back-button="true"
5+
hide-back-button="!$ctrl.useProjectTemplate"
66
step-class="order-service-wizard-step"
77
wizard-ready="$ctrl.wizardReady"
88
next-title="$ctrl.nextTitle"
@@ -11,7 +11,7 @@
1111
on-cancel="$ctrl.close()"
1212
wizard-done="$ctrl.wizardDone"
1313
current-step="$ctrl.currentStep"
14-
class="pf-wizard-no-back">
14+
ng-class="{'pf-wizard-no-back': !$ctrl.useProjectTemplate}">
1515
<pf-wizard-step ng-repeat="step in $ctrl.steps track by step.id"
1616
step-title="{{step.label}}"
1717
wz-disabled="{{step.hidden}}"
@@ -22,7 +22,7 @@
2222
step-id="{{step.id}}"
2323
step-priority="{{$index}}">
2424
<div class="wizard-pf-main-inner-shadow-covers">
25-
<div class="order-service-details">
25+
<div class="order-service-details" ng-if="!$ctrl.selectStep.selected">
2626
<div class="order-service-details-top">
2727
<div class="service-icon">
2828
<span class="icon {{$ctrl.iconClass}}"></span>
@@ -42,7 +42,7 @@
4242
<p ng-bind-html="$ctrl.template | description | linky : '_blank'" class="description"></p>
4343
</div>
4444
</div>
45-
<div class="order-service-config">
45+
<div class="order-service-config" ng-class="{'order-service-config-single-column': $ctrl.selectStep.selected}">
4646
<div ng-if="step.selected" ng-include="step.view" class="wizard-pf-main-form-contents"></div>
4747
</div>
4848
</div>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="osc-form">
22
<form name="$ctrl.form">
3-
<process-template template="$ctrl.template" is-dialog="true"></process-template>
3+
<process-template template="$ctrl.template" project="$ctrl.preSelectedProject" on-project-selected="$ctrl.onProjectSelected" available-projects="$ctrl.unfilteredProjects" is-dialog="true"></process-template>
44
</form>
55
</div>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<next-steps
22
project="$ctrl.selectedProject"
33
project-name="$ctrl.selectedProject.metadata.name"
4-
login-base-url="$ctrl.loginBaseUrl">
4+
login-base-url="$ctrl.loginBaseUrl"
5+
on-continue="$ctrl.close">
56
</next-steps>

0 commit comments

Comments
 (0)