diff --git a/gateway/assets/img/icons/ic_info_outline_black_24px.svg b/gateway/assets/img/icons/ic_info_outline_black_24px.svg new file mode 100644 index 00000000..c999d630 --- /dev/null +++ b/gateway/assets/img/icons/ic_info_outline_black_24px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gateway/assets/img/icons/ic_search_black_24px.svg b/gateway/assets/img/icons/ic_search_black_24px.svg new file mode 100644 index 00000000..ccc84b62 --- /dev/null +++ b/gateway/assets/img/icons/ic_search_black_24px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gateway/assets/img/icons/ic_shop_two_black_24px.svg b/gateway/assets/img/icons/ic_shop_two_black_24px.svg new file mode 100644 index 00000000..93b75621 --- /dev/null +++ b/gateway/assets/img/icons/ic_shop_two_black_24px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gateway/assets/index.html b/gateway/assets/index.html index da38cf30..f1300293 100644 --- a/gateway/assets/index.html +++ b/gateway/assets/index.html @@ -36,10 +36,19 @@ - Deploy New Function - - + + +

Deploy New Function

+
+
+ + + + + + +

{{function.name}}

@@ -166,7 +175,8 @@ - + + diff --git a/gateway/assets/newfunction.html b/gateway/assets/newfunction.html deleted file mode 100644 index 39b8a7df..00000000 --- a/gateway/assets/newfunction.html +++ /dev/null @@ -1,61 +0,0 @@ - - -
-

Deploy A New Function

- - - - -
-
- - - - - - - -
-
- - Docker image name and tag to use for function i.e. functions/alpine:latest - - - -
-
- - Name of the function - must be a valid DNS entry - - - -
-
- - Process to run as your function i.e. 'env' or 'shasum'. Ignore if using OpenFaaS templates - - - -
-
- - Docker Swarm network, not required for other providers. Default: func_functions - - - -
-
- {{ validationError }} -
-
-
- - - - Close Dialog - - - Deploy - - -
diff --git a/gateway/assets/script/bootstrap.js b/gateway/assets/script/bootstrap.js index 3ee6992b..a706c218 100644 --- a/gateway/assets/script/bootstrap.js +++ b/gateway/assets/script/bootstrap.js @@ -2,10 +2,11 @@ // Copyright (c) Alex Ellis 2017. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -var app = angular.module('faasGateway', ['ngMaterial']); +var app = angular.module('faasGateway', ['ngMaterial', 'faasGateway.funcStore']); app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$mdDialog', '$mdToast', '$mdSidenav', function($scope, $log, $http, $location, $timeout, $mdDialog, $mdToast, $mdSidenav) { + var newFuncTabIdx = 0; $scope.functions = []; $scope.invocationInProgress = false; $scope.invocationRequest = ""; @@ -128,7 +129,7 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md $mdDialog.show({ parent: parentEl, targetEvent: $event, - templateUrl: "newfunction.html", + templateUrl: "templates/newfunction.html", locals: { item: $scope.functionTemplate }, @@ -137,11 +138,33 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md }; var DialogController = function($scope, $mdDialog, item) { + $scope.selectedTabIdx = newFuncTabIdx; $scope.item = item; + $scope.selectedFunc = null; $scope.closeDialog = function() { $mdDialog.hide(); }; + $scope.onFuncSelected = function(func) { + $scope.item.image = func.image; + $scope.item.service = func.name; + $scope.item.envProcess = func.fprocess; + $scope.item.network = func.network; + $scope.selectedFunc = func; + } + + $scope.onTabSelect = function(idx) { + newFuncTabIdx = idx; + } + + $scope.onStoreTabDeselect = function() { + $scope.selectedFunc = null; + } + + $scope.onManualTabDeselect = function() { + $scope.item = {}; + } + $scope.createFunc = function() { var options = { url: "/system/functions", diff --git a/gateway/assets/script/funcstore.js b/gateway/assets/script/funcstore.js new file mode 100644 index 00000000..0fd8aa88 --- /dev/null +++ b/gateway/assets/script/funcstore.js @@ -0,0 +1,76 @@ +var funcStoreModule = angular.module('faasGateway.funcStore', ['ngMaterial']); + +funcStoreModule.service('FuncStoreService', ['$http', function ($http) { + var self = this; + this.fetchStore = function (url) { + return $http.get(url) + .then(function (resp) { + return resp.data; + }); + }; + +}]); + +funcStoreModule.component('funcStore', { + templateUrl: 'templates/funcstore.html', + bindings: { + selectedFunc: '<', + onSelected: '&', + }, + controller: ['FuncStoreService', '$mdDialog', function FuncStoreController(FuncStoreService, $mdDialog) { + var self = this; + + this.storeUrl = 'https://raw.githubusercontent.com/openfaas/store/master/store.json'; + this.selectedFunc = null; + this.functions = []; + this.message = ''; + this.searchText = ''; + + this.search = function (func) { + // filter with title and description + if (!self.searchText || (func.title.toLowerCase().indexOf(self.searchText.toLowerCase()) != -1) || + (func.description.toLowerCase().indexOf(self.searchText.toLowerCase()) != -1)) { + return true; + } + return false; + } + + this.select = function (func, event) { + self.selectedFunc = func; + self.onSelected()(func, event); + }; + + this.loadStore = function () { + self.loading = true; + self.functions = []; + self.message = ''; + FuncStoreService.fetchStore(self.storeUrl) + .then(function (data) { + self.loading = false; + self.functions = data; + }) + .catch(function (err) { + console.error(err); + self.loading = false; + self.message = 'Unable to reach GitHub.com'; + }); + } + + this.showInfo = function (func, event) { + $mdDialog.show( + $mdDialog.alert() + .multiple(true) + .parent(angular.element(document.querySelector('#newfunction-dialog'))) + .clickOutsideToClose(true) + .title(func.title) + .textContent(func.description) + .ariaLabel(func.title) + .ok('OK') + .targetEvent(event) + ); + } + + this.loadStore(); + + }] +}); \ No newline at end of file diff --git a/gateway/assets/style/bootstrap.css b/gateway/assets/style/bootstrap.css index a8cf57e6..61bbddfc 100644 --- a/gateway/assets/style/bootstrap.css +++ b/gateway/assets/style/bootstrap.css @@ -54,3 +54,16 @@ md-input-container .md-errors-spacer { color: red; height: 52px; } + +.primary-item .md-list-item-inner{ + color: rgb(63,81,181); + font-weight: 500; +} + +span.md-avatar { + font-weight: bold; + line-height: 40px; + text-align: center; + background-color: #1398D6; + color: white; +} diff --git a/gateway/assets/templates/funcstore.html b/gateway/assets/templates/funcstore.html new file mode 100644 index 00000000..2aceb3d3 --- /dev/null +++ b/gateway/assets/templates/funcstore.html @@ -0,0 +1,25 @@ +
+

{{ $ctrl.message }}

+
+
+ + + + + +
+ +
+ + + {{func.name}} + {{func.title | limitTo:1}} +
+

{{ func.title }}

+

{{ func.description }}

+
+ +
+
+
\ No newline at end of file diff --git a/gateway/assets/templates/newfunction.html b/gateway/assets/templates/newfunction.html new file mode 100644 index 00000000..659c154f --- /dev/null +++ b/gateway/assets/templates/newfunction.html @@ -0,0 +1,71 @@ + + +
+

Deploy A New Function

+ + + + +
+
+ + + + + + + + + + +
+ +
+ +
+
+ + Docker image name and tag to use for function i.e. functions/alpine:latest + + + +
+
+ + Name of the function - must be a valid DNS entry + + + +
+
+ + Process to run as your function i.e. 'env' or 'shasum'. Ignore if using OpenFaaS templates + + + +
+
+ + Docker Swarm network, not required for other providers. Default: func_functions + + + +
+
+ {{ validationError }} +
+
+
+
+
+
+ + + + Close Dialog + + + Deploy + + +