Skip to content

Commit

Permalink
Add 'Select from Project' wizard to allow project templates/images to…
Browse files Browse the repository at this point in the history
… be imported
  • Loading branch information
jeff-phillips-18 committed Sep 6, 2017
1 parent 4f8b2cf commit 197c465
Show file tree
Hide file tree
Showing 16 changed files with 453 additions and 56 deletions.
4 changes: 4 additions & 0 deletions app/scripts/controllers/landingPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ angular.module('openshiftConsole')
_.set($scope, 'ordering.panelName', 'fromFile');
};

$scope.fromProjectSelected = function() {
_.set($scope, 'ordering.panelName', 'fromProject');
};

AuthService.withUser().then(function() {
var includeTemplates = !_.get(Constants, 'ENABLE_TECH_PREVIEW_FEATURE.template_service_broker');
Catalog.getCatalogItems(includeTemplates).then(_.spread(function(items, errorMessage) {
Expand Down
2 changes: 2 additions & 0 deletions app/scripts/directives/processTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
bindings: {
template: '<',
project: '<',
onProjectSelected: '<',
availableProjects: '<',
prefillParameters: '<',
isDialog: '<'
},
Expand Down
168 changes: 165 additions & 3 deletions app/scripts/directives/processTemplateDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,46 @@
angular.module('openshiftConsole').component('processTemplateDialog', {
controller: [
'$scope',
'$filter',
'Catalog',
'DataService',
'KeywordService',
'NotificationsService',
'ProjectsService',
'RecentlyViewedProjectsService',
ProcessTemplateDialog
],
controllerAs: '$ctrl',
bindings: {
template: '<',
project: '<',
useProjectTemplate: '<',
onDialogClosed: '&'
},
templateUrl: 'views/directives/process-template-dialog.html'
});

function ProcessTemplateDialog($scope, DataService) {
function ProcessTemplateDialog($scope,
$filter,
Catalog,
DataService,
KeywordService,
NotificationsService,
ProjectsService,
RecentlyViewedProjectsService) {
var ctrl = this;
var validityWatcher;

ctrl.selectStep = {
id: 'projectTemplates',
label: 'Selection',
view: 'views/directives/process-template-dialog/process-template-select.html',
hidden: ctrl.useProjectTemplate !== true,
allowed: true,
valid: false,
onShow: showSelect
};

ctrl.configStep = {
id: 'configuration',
label: 'Configuration',
Expand All @@ -43,6 +68,38 @@

ctrl.$onInit = function() {
ctrl.loginBaseUrl = DataService.openshiftAPIBaseUrl();
ctrl.preSelectedProject = ctrl.selectedProject = ctrl.project;
listProjects();

ctrl.projectEmptyState = {
icon: 'pficon pficon-info',
title: 'No Project Selected',
info: 'Please select a project from the dropdown to load Templates from that project.'
};

ctrl.templatesEmptyState = {
icon: 'pficon pficon-info',
title: 'No Templates',
info: 'The selected project has no templates available to import.'
};

ctrl.filterConfig = {
fields: [
{
id: 'keyword',
title: 'Keyword',
placeholder: 'Filter by Keyword',
filterType: 'text'
}
],
inlineResults: true,
showTotalCountResults: true,
itemsLabel: 'Item',
itemsLabelPlural: 'Items',
resultsCount: 0,
appliedFilters: [],
onFilterChange: filterChange
};
};

ctrl.$onChanges = function(changes) {
Expand All @@ -52,6 +109,9 @@
ctrl.iconClass = getIconClass();
}
}
if (changes.useProjectTemplate) {
initializeSteps();
}
};

$scope.$on('templateInstantiated', function(event, message) {
Expand Down Expand Up @@ -85,13 +145,49 @@
}
};

ctrl.onProjectSelected = function(project) {
ctrl.selectedProject = project;
ctrl.configStep.valid = $scope.$ctrl.form.$valid && ctrl.selectedProject;
};

ctrl.templateSelected = function(template) {
ctrl.selectedTemplate = template;
ctrl.template = _.get(template, 'resource');
ctrl.selectStep.valid = !!template;
};

ctrl.templateProjectChange = function () {
ctrl.templateProjectName = _.get(ctrl.templateProject, 'metadata.name');

// Get the templates for the selected project
ctrl.catalogItems = {};
ctrl.templateSelected();

Catalog.getProjectCatalogItems(ctrl.templateProjectName, false, true).then( _.spread(function(catalogServiceItems, errorMessage) {
ctrl.catalogItems = catalogServiceItems;
ctrl.totalCount = ctrl.catalogItems.length;
filterItems();

if (errorMessage) {
NotificationsService.addNotification(
{
type: "error",
message: errorMessage
}
);
}
}));
};

function getIconClass() {
var icon = _.get(ctrl, 'template.metadata.annotations.iconClass', 'fa fa-clone');
return (icon.indexOf('icon-') !== -1) ? 'font-icon ' + icon : icon;
}

function initializeSteps() {
ctrl.steps = [ctrl.configStep, ctrl.resultsStep];
if (!ctrl.steps) {
ctrl.steps = [ctrl.selectStep, ctrl.configStep, ctrl.resultsStep];
}
}

function clearValidityWatcher() {
Expand All @@ -101,19 +197,30 @@
}
}

function showSelect() {
ctrl.selectStep.selected = true;
ctrl.configStep.selected = false;
ctrl.resultsStep.selected = false;
ctrl.nextTitle = "Next >";
clearValidityWatcher();
listProjects();
}

function showConfig() {
ctrl.selectStep.selected = false;
ctrl.configStep.selected = true;
ctrl.resultsStep.selected = false;
ctrl.nextTitle = "Create";
ctrl.resultsStep.allowed = ctrl.configStep.valid;

validityWatcher = $scope.$watch("$ctrl.form.$valid", function(isValid) {
ctrl.configStep.valid = isValid;
ctrl.configStep.valid = isValid && ctrl.selectedProject;
ctrl.resultsStep.allowed = isValid;
});
}

function showResults() {
ctrl.selectStep.selected = false;
ctrl.configStep.selected = false;
ctrl.resultsStep.selected = true;
ctrl.nextTitle = "Close";
Expand All @@ -124,5 +231,60 @@
function instantiateTemplate() {
$scope.$broadcast('instantiateTemplate');
}

function filterForKeywords(searchText, items) {
return KeywordService.filterForKeywords(items, ['name', 'tags'], KeywordService.generateKeywords(searchText));
}

function filterChange(filters) {
ctrl.filterConfig.appliedFilters = filters;
filterItems();
}

function filterItems() {
ctrl.filteredItems = ctrl.catalogItems;
if (ctrl.filterConfig.appliedFilters && ctrl.filterConfig.appliedFilters.length > 0) {
_.each(ctrl.filterConfig.appliedFilters, function(filter) {
ctrl.filteredItems = filterForKeywords(filter.value, ctrl.filteredItems);
});
}

// Deselect the currently selected template if it was filtered out
if (!_.includes(ctrl.filteredItems, ctrl.selectedTemplate)) {
ctrl.templateSelected();
}

updateFilterControls();
}

function updateFilterControls() {
ctrl.filterConfig.resultsCount = ctrl.filteredItems.length;

if (ctrl.totalCount <= 1) {
$('.filter-pf.filter-fields input').attr('disabled', '');
} else {
$('.filter-pf.filter-fields input').removeAttr("disabled");
}
}

var updateProjects = function() {
var filteredProjects = _.reject(ctrl.unfilteredProjects, 'metadata.deletionTimestamp');
var projects = _.sortBy(filteredProjects, $filter('displayName'));
ctrl.searchEnabled = !_.isEmpty(filteredProjects);

ctrl.templateProjects = RecentlyViewedProjectsService.orderByMostRecentlyViewed(projects);
};

function listProjects() {
if (!ctrl.unfilteredProjects) {
ProjectsService.list().then(function(projectData) {
ctrl.unfilteredProjects = _.toArray(projectData.by("metadata.name"));
}, function() {
ctrl.unfilteredProjects = [];
}).finally(function() {
updateProjects();
});
}
}
}
})();
48 changes: 48 additions & 0 deletions app/styles/_core.less
Original file line number Diff line number Diff line change
Expand Up @@ -1246,3 +1246,51 @@ pre.clipped {
width: 30px;
}
}

.order-service-config {
.order-services-filter {
margin-left: 0;
}
.blank-slate-pf {
margin-bottom: 0;
padding-bottom: 0;
}
.select-project-for-template {
border-bottom: solid 1px @color-pf-black-300;
padding-bottom: 10px;

> h2 {
margin-bottom: 20px;
margin-top: 0;
}
.ui-select-container {
display: inline-block;
width: 275px;
}
}
.services-item {
&.show-selection {
// Clear focus settings, keep before active settings
&:focus {
color: @text-color;
.services-item-icon:after {
border: none;
}

.services-item-name {
color: @text-color;
}
}
&.active {
color: @link-hover-color;
.services-item-icon:after {
border: 2px solid @link-color;
}
.services-item-name {
color: @link-hover-color;
}
}
}
}
}

3 changes: 3 additions & 0 deletions app/styles/_overlay-forms.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.order-service-config-single-column {
width: 100%;
@media (min-width: 768px) {
padding-left: 0;
}
}

.wizard-pf-main {
Expand Down
2 changes: 2 additions & 0 deletions app/views/directives/header/project-header.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<li ng-if-start="catalogLandingPageEnabled" role="menuitem"><a href="/">Browse Catalog</a></li>
<li role="menuitem"><a href="" ng-click="showOrderingPanel('deployImage')">Deploy Image</a></li>
<li ng-if-end role="menuitem"><a href="" ng-click="showOrderingPanel('fromFile')">Import YAML / JSON</a></li>
<li ng-if-end role="menuitem"><a href="" ng-click="showOrderingPanel('fromProject')">Select from Project</a></li>
</ul>
</div>
<div row
Expand All @@ -51,4 +52,5 @@
<overlay-panel show-panel="ordering.panelName" show-close="true" handle-close="closeOrderingPanel">
<deploy-image-dialog ng-if="ordering.panelName === 'deployImage'" project="project" context="context" on-dialog-closed="closeOrderingPanel"></deploy-image-dialog>
<from-file-dialog ng-if="ordering.panelName === 'fromFile'" project="project" context="context" on-dialog-closed="closeOrderingPanel"></from-file-dialog>
<process-template-dialog ng-if="ordering.panelName === 'fromProject'" project="project" use-project-template="true" on-dialog-closed="closeOrderingPanel"></process-template-dialog>
</overlay-panel>
8 changes: 4 additions & 4 deletions app/views/directives/process-template-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<pf-wizard
hide-header="true"
hide-sidebar="true"
hide-back-button="true"
hide-back-button="!$ctrl.useProjectTemplate"
step-class="order-service-wizard-step"
wizard-ready="$ctrl.wizardReady"
next-title="$ctrl.nextTitle"
Expand All @@ -11,7 +11,7 @@
on-cancel="$ctrl.close()"
wizard-done="$ctrl.wizardDone"
current-step="$ctrl.currentStep"
class="pf-wizard-no-back">
ng-class="{'pf-wizard-no-back': !$ctrl.useProjectTemplate}">
<pf-wizard-step ng-repeat="step in $ctrl.steps track by step.id"
step-title="{{step.label}}"
wz-disabled="{{step.hidden}}"
Expand All @@ -22,7 +22,7 @@
step-id="{{step.id}}"
step-priority="{{$index}}">
<div class="wizard-pf-main-inner-shadow-covers">
<div class="order-service-details">
<div class="order-service-details" ng-if="!$ctrl.selectStep.selected">
<div class="order-service-details-top">
<div class="service-icon">
<span class="icon {{$ctrl.iconClass}}"></span>
Expand All @@ -42,7 +42,7 @@
<p ng-bind-html="$ctrl.template | description | linky : '_blank'" class="description"></p>
</div>
</div>
<div class="order-service-config">
<div class="order-service-config" ng-class="{'order-service-config-single-column': $ctrl.selectStep.selected}">
<div ng-if="step.selected" ng-include="step.view" class="wizard-pf-main-form-contents"></div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="osc-form">
<form name="$ctrl.form">
<process-template template="$ctrl.template" is-dialog="true"></process-template>
<process-template template="$ctrl.template" project="$ctrl.preSelectedProject" on-project-selected="$ctrl.onProjectSelected" available-projects="$ctrl.unfilteredProjects" is-dialog="true"></process-template>
</form>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<next-steps
project="$ctrl.selectedProject"
project-name="$ctrl.selectedProject.metadata.name"
login-base-url="$ctrl.loginBaseUrl">
login-base-url="$ctrl.loginBaseUrl"
on-continue="$ctrl.close">
</next-steps>
Loading

0 comments on commit 197c465

Please sign in to comment.