From acd42f5d45ac725ae631694110987dce8d9398e9 Mon Sep 17 00:00:00 2001 From: Georg Traar Date: Sun, 17 Oct 2021 11:16:47 +0200 Subject: [PATCH 1/3] Fork UDF section from VIEW section --- app/app.components.js | 2 + app/app.module.js | 12 ++ app/scripts/controllers/common.js | 6 +- app/scripts/controllers/udfs.js | 260 ++++++++++++++++++++++++++++++ app/scripts/services/stats.js | 9 +- app/scripts/services/udfinfo.js | 75 +++++++++ app/static/i18n/en.json | 15 ++ app/styles/styles.scss | 1 + app/styles/views/_common.scss | 2 + app/styles/views/_udfs.scss | 60 +++++++ app/views/udf-detail.html | 61 +++++++ app/views/udflist.html | 48 ++++++ app/views/udfs.html | 15 ++ 13 files changed, 562 insertions(+), 4 deletions(-) create mode 100644 app/scripts/controllers/udfs.js create mode 100644 app/scripts/services/udfinfo.js create mode 100644 app/styles/views/_udfs.scss create mode 100644 app/views/udf-detail.html create mode 100644 app/views/udflist.html create mode 100644 app/views/udfs.html diff --git a/app/app.components.js b/app/app.components.js index eb0288a0c..e9feb52ef 100644 --- a/app/app.components.js +++ b/app/app.components.js @@ -8,6 +8,7 @@ import './scripts/services/health'; import './scripts/services/stats'; import './scripts/services/tableinfo'; import './scripts/services/shardinfo'; +import './scripts/services/udfinfo'; import './scripts/services/viewinfo'; import './scripts/services/nodeinfo'; import './scripts/services/checks'; @@ -20,6 +21,7 @@ import './scripts/controllers/feed'; import './scripts/controllers/overview'; import './scripts/controllers/console'; import './scripts/controllers/tables'; +import './scripts/controllers/udfs'; import './scripts/controllers/views'; import './scripts/controllers/cluster'; diff --git a/app/app.module.js b/app/app.module.js index d791b3b29..aac1986d0 100644 --- a/app/app.module.js +++ b/app/app.module.js @@ -19,6 +19,8 @@ var MODULES = [ 'console', 'tables', 'tableinfo', + 'udfs', + 'udfinfo', 'views', 'viewinfo', 'shardinfo', @@ -53,6 +55,16 @@ var ROUTING = { 'url': '/:table_schema/:table_name', 'template': '', }, + '/udfs': { + 'name': 'udfs', + 'url': '/udfs', + 'template': '', + }, + '/udfs/:schema/:name': { + 'name': 'udfs.udf', + 'url': '/:schema/:name', + 'template': '', + }, '/views': { 'name': 'views', 'url': '/views', diff --git a/app/scripts/controllers/common.js b/app/scripts/controllers/common.js index 0b335dd91..1b76c1ba3 100644 --- a/app/scripts/controllers/common.js +++ b/app/scripts/controllers/common.js @@ -314,15 +314,17 @@ commons.run(function(NavigationService, $translate, $filter, $rootScope) { NavigationService.addNavBarElement('static/assets/icon-console.svg', $filter('translate', 'NAVIGATION.CONSOLE'), '/console', 20, "console"); NavigationService.addNavBarElement('static/assets/icon-table.svg', $filter('translate', 'NAVIGATION.TABLE'), '/tables', 30, "tables"); NavigationService.addNavBarElement('static/assets/icon-view.svg', $filter('translate', 'NAVIGATION.VIEW'), '/views', 40, "views"); - NavigationService.addNavBarElement('static/assets/icon-cluster.svg', $filter('translate', 'NAVIGATION.CLUSTER'), '/nodes', 50, "nodes"); + NavigationService.addNavBarElement('static/assets/icon-monitoring.svg', $filter('translate', 'NAVIGATION.UDF'), '/udfs', 50, "udfs"); + NavigationService.addNavBarElement('static/assets/icon-cluster.svg', $filter('translate', 'NAVIGATION.CLUSTER'), '/nodes', 60, "nodes"); // Update Navbar Elements if Language is Changed $rootScope.$on('$translateChangeSuccess', function() { - $translate(['NAVIGATION.OVERVIEW', 'NAVIGATION.CONSOLE', 'NAVIGATION.TABLE', 'NAVIGATION.VIEW', 'NAVIGATION.CLUSTER']).then(function(i18n) { + $translate(['NAVIGATION.OVERVIEW', 'NAVIGATION.CONSOLE', 'NAVIGATION.TABLE', 'NAVIGATION.VIEWS', 'NAVIGATION.UDF', 'NAVIGATION.CLUSTER']).then(function(i18n) { NavigationService.updateNavBarElement('/', i18n['NAVIGATION.OVERVIEW']); NavigationService.updateNavBarElement('/console', i18n['NAVIGATION.CONSOLE']); NavigationService.updateNavBarElement('/tables', i18n['NAVIGATION.TABLE']); NavigationService.updateNavBarElement('/views', i18n['NAVIGATION.VIEW']); + NavigationService.updateNavBarElement('/udfs', i18n['NAVIGATION.UDF']); NavigationService.updateNavBarElement('/nodes', i18n['NAVIGATION.CLUSTER']); }); }); diff --git a/app/scripts/controllers/udfs.js b/app/scripts/controllers/udfs.js new file mode 100644 index 000000000..4559a5a24 --- /dev/null +++ b/app/scripts/controllers/udfs.js @@ -0,0 +1,260 @@ +'use strict'; + +angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) + .provider('TabNavigationInfo', function () { + this.collapsed = [false, true]; // must match $scope.udfs of TablesController + this.$get = () => { + var collapsed = this.collapsed; + return { + 'collapsed': collapsed, + 'toggleIndex': (i) => { + collapsed[i] = !collapsed[i]; + }, + 'collapseIndex': (i) => { + collapsed[i] = true; + }, + 'unCollapseIndex': (i) => { + collapsed[i] = false; + } + }; + }; + }) + .directive('udfs', function () { + return { + restrict: 'E', + replace: true, + scope: {}, + templateUrl: 'static/views/udfs.html', + controllerAs: 'UdfsController', + controller: function (ClusterState, $scope, ClusterEventsHandler) { + var hideIfEmpty = () => { + $scope.empty = ClusterState.data.udfs.length === 0; + }; + + // initial state + hideIfEmpty(); + + ClusterEventsHandler.register('STATE_REFRESHED', 'UdfsController', hideIfEmpty); + + $scope.$on('$destroy', function () { + ClusterEventsHandler.remove('STATE_REFRESHED', 'UdfsController'); + }); + } + }; + }) + .directive('udfDetail', function () { + return { + restrict: 'E', + replace: true, + scope: {}, + templateUrl: 'static/views/udf-detail.html', + controllerAs: 'UDFDetailController', + controller: function ($scope, $location, $log, $timeout, $state, + SQLQuery, queryResultToObjects, roundWithUnitFilter, bytesFilter, UdfList, + ClusterEventsHandler, ClusterState) { + + const NESTED_COL_REGEX = /([^\s]+)(\[\'([^\s]+)\'])+/i; + const COLUMNS_QUERY = 'SELECT quote_ident(column_name) as column_name, upper(data_type) AS column_type ' + + 'FROM information_schema.columns ' + + 'WHERE table_schema = ? AND table_name = ?'; + + $scope.executeQuery = (query) => { + $location.search({'query': query}); + $location.path('/console'); + }; + + // sidebar button handler (mobile udf) + $scope.toggleSidebar = function () { + $('#page-viewport') + .toggleClass('show-sidebar'); + $('.menu-toggle i.fa') + .toggleClass('fa-angle-double-right') + .toggleClass('fa-angle-double-left'); + }; + + // bind tooltips + $('[rel=tooltip]').tooltip({ + placement: 'top' + }); + + var isNestedColumn = (col) => col.match(NESTED_COL_REGEX); + + var constructQuery = (schema, name, rows) => { + var query = 'CREATE OR REPLACE FUNCTION "' + schema + '"."' + name + '"'; + query += '\nRETURNS '; + query += '\nLANGUAGE ' + 'JAVASCRIPT'; + query += '\nAS '; + query += '\n\'' + 'function'; + query += '\n\';'; + return query; + }; + + var render = (schema, name) => { + $scope.nothingSelected = false; + $scope.renderSiderbar = true; + + if (schema && name) { + SQLQuery.execute(COLUMNS_QUERY, [schema, name], false, false, false, false) + .then((q) => { + $scope.columns = queryResultToObjects(q, q.cols); + $scope.query = constructQuery(schema, name, $scope.columns); + }, () => { + $scope.columns = []; + }); + } + }; + + var updateUDF = () => { + var name = $state.params.name; + var schema = $state.params.schema; + var udfs = ClusterState.data.udfs; + + var hasUdfs = udfs.length > 0; + $scope.renderSidebar = hasUdfs; + $scope.nothingSelected = !hasUdfs; + if (hasUdfs) { + var current = udfs.filter((o) => o.name == name && o.schema == schema); + current = current.length ? current[0] : udfs[0]; + $scope.udf = current; + $scope.udf.label = current.schema + '.' + current.name; + + } else { + $scope.udf = null; + $scope.columns = []; + } + }; + + ClusterEventsHandler.register('STATE_REFRESHED', + 'UDFDetailController', + updateUDF); + + $scope.$on('$destroy', function () { + ClusterEventsHandler.remove('STATE_REFRESHED', 'UDFDetailController'); + }); + + updateUDF(); + render($state.params.schema, $state.params.name); + } + }; + }) + .directive('udfList', function () { + return { + restrict: 'E', + replace: true, + scope: {}, + templateUrl: 'static/views/udflist.html', + controllerAs: 'UdfListController', + controller: function ($scope, $state, TabNavigationInfo, ClusterEventsHandler, ClusterState) { + $scope.collapsed = true; + + $scope.udfFilter = (item) => { + return (!$scope.search || (item.fqn.toLowerCase().indexOf($scope.search) != -1)); + }; + + $scope.clearFilter = function () { + $scope.search = ''; + }; + + $scope.isActive = (schema, name) => { + return name === $state.params.name && schema === $state.params.schema; + }; + + var toggleClasses = (i) => { + $('#nav-tabs-' + i) + .collapse('toggle'); + $('#nav-tabs-header-' + i + ' i.fa') + .toggleClass('fa-caret-down') + .toggleClass('fa-caret-right'); + }; + + $scope.toggleElements = (i) => { + toggleClasses(i); + TabNavigationInfo.toggleIndex(i); + }; + + $scope.isCollapsed = (i) => { + return TabNavigationInfo.collapsed[i]; + }; + + $scope.collapseAll = () => { + var idx; + for (idx in $scope.udfs) { + toggleClasses(idx); + TabNavigationInfo.collapseIndex(idx); + } + $scope.collapsed = true; + }; + + $scope.unCollapseAll = () => { + var idx; + for (idx in $scope.udfs) { + toggleClasses(idx); + TabNavigationInfo.unCollapseIndex(idx); + } + $scope.collapsed = false; + }; + + var filterBySchemaName = (schema) => (o) => o.schema === schema; + + var updateUdfList = () => { + var udfs = ClusterState.data.udfs; + var hasUdfs = udfs.length > 0; + $scope.renderSidebar = hasUdfs; + $scope.udfs = []; + if (hasUdfs) { + // use name and schema from first item + if (!$scope.name || !$scope.schema) { + $scope.schema = udfs[0].schema; + $scope.name = udfs[0].name; + $state.go('udfs.udf', { + schema: $scope.schema, + name: $scope.name + }); + } + + var idx, + name; + var customSchemas = []; + for (idx in udfs) { + name = udfs[idx].schema; + if (name == 'doc' || name == 'blob' || customSchemas.indexOf(name) > -1) { + continue; + } + customSchemas.push(name); + } + + $scope.udfs.push({ + display_name: 'Doc', + udfs: udfs.filter(filterBySchemaName('doc')), + schema: 'doc' + }); + for (idx in customSchemas) { + name = customSchemas[idx]; + $scope.udfs.push({ + display_name: name, + udfs: udfs.filter(filterBySchemaName(name)), + schema: name + }); + } + } + }; + + var render = (schema, name) => { + $scope.name = name; + $scope.schema = schema; + $scope.renderSidebar = true; + }; + + ClusterEventsHandler.register('STATE_REFRESHED', + 'UdfListController', + updateUdfList); + + $scope.$on('$destroy', function () { + ClusterEventsHandler.remove('STATE_REFRESHED', 'UdfListController'); + }); + + updateUdfList(); + render($state.params.schema, $state.params.name); + } + }; + }); diff --git a/app/scripts/services/stats.js b/app/scripts/services/stats.js index 6b40fcd92..17d575d9d 100644 --- a/app/scripts/services/stats.js +++ b/app/scripts/services/stats.js @@ -8,7 +8,7 @@ import './clusterEventsHandler'; const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo', 'events']) .factory('ClusterState', function ($http, $interval, $timeout, $log, $q, $rootScope, - baseURI, SQLQuery, queryResultToObjects, TableList, Health, ShardInfo, NodeInfo, ViewInfo, ViewList, ClusterEventsHandler) { + baseURI, SQLQuery, queryResultToObjects, TableList, Health, ShardInfo, NodeInfo, UdfInfo, UdfList, ViewInfo, ViewList, ClusterEventsHandler) { var reachabilityInterval, ClusterStateInterval; @@ -20,6 +20,7 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo', var data = { online: true, tables: [], + udfs: [], views: [], shards: [], partitions: [], @@ -166,6 +167,7 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo', ShardInfo.executeRecoveryStmt(), NodeInfo.executeClusterQuery(), NodeInfo.executeNodeQuery(), + UdfInfo.executeUdfStmt(), ViewInfo.executeViewStmt() ]).then(function (values) { @@ -213,7 +215,10 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo', data.tables = tableinfo.data.tables; } - var viewInfo = ViewList.execute(values[6]); + var udfInfo = UdfList.execute(values[6]); + data.udfs = udfInfo.data.udfs; + + var viewInfo = ViewList.execute(values[7]); data.views = viewInfo.data.views; ClusterEventsHandler.trigger('STATE_REFRESHED'); diff --git a/app/scripts/services/udfinfo.js b/app/scripts/services/udfinfo.js new file mode 100644 index 000000000..8541df351 --- /dev/null +++ b/app/scripts/services/udfinfo.js @@ -0,0 +1,75 @@ +'use strict'; +import './sql'; + +const udfinfo = angular.module('udfinfo', ['sql']) + .factory('UdfInfo', function($q, SQLQuery, queryResultToObjects) { + var udfInfo = { + deferred: $q.defer() + }; + + const UDFS_STMT = `SELECT + routine_name as "name", + routine_schema AS "schema", + format('%s.%s', routine_name, routine_schema) AS "fqn", + routine_definition AS "definition", + (regexp_replace(specific_name, '.*\\((.*)\\)', '$1')) as "input_types", + (data_type) AS "return_type", + routine_body AS "language" +FROM information_schema.routines +where routine_type = 'FUNCTION'; +` + + const COLS = ['name', 'schema', 'fqn', 'definition', 'input_types', 'return_type', 'language']; + + udfInfo.executeUdfStmt = () => { + var deferred = $q.defer(); + var promise = deferred.promise; + + SQLQuery.execute(UDFS_STMT, {}, false, false, false, false) + .then((q) => { + deferred.resolve(queryResultToObjects(q, COLS)); + }, () => { + deferred.reject(); + }); + + return promise; + }; + + return udfInfo; + }) + .factory('UdfList', function() { + + var data = { + 'udfs': [] + }; + + var update = (success, udfs) => { + if (success && udfs && udfs.length) { + data.udfs = udfs; + } else { + data.udfs = []; + } + return { + 'success': success, + 'data': data + }; + }; + + var fetch = (udfs) => { + if (udfs && udfs.length) { + return update(true, udfs); + } else { + return update(false, []); + } + }; + + // initialize + fetch(); + + return { + 'data': data, + 'execute': fetch + }; + }); + +export default udfinfo; diff --git a/app/static/i18n/en.json b/app/static/i18n/en.json index 9150b74d2..f135955e4 100644 --- a/app/static/i18n/en.json +++ b/app/static/i18n/en.json @@ -23,6 +23,7 @@ "OVERVIEW": "Overview", "CONSOLE": "Console", "TABLE": "Tables", + "UDF": "User Defined Functions", "VIEW": "Views", "SHARDS": "Shards", "CLUSTER": "Cluster", @@ -101,6 +102,20 @@ "SCHEMA": "Schema", "TYPE": "Type" }, + "UDF": { + "TITLE": "UDFs", + "VOID_MESSAGE": "There are no udfs created yet.", + "VOID_DETAILS": "Use the {{ statement }} statement to create new udfs.", + "QUERY_UDF": "Query udf", + "REPLACE_UDF": "Replace UDF", + "PARAMETERS": "Parameters", + "RETURN_TYPE": "Return Type", + "LANGUAGE": "Language", + "NAME": "Name", + "TYPE": "Type", + "DEFINITION": "Definition", + "COLUMNS": "Columns" + }, "VIEW": { "TITLE": "Views", "VOID_MESSAGE": "There are no views created yet.", diff --git a/app/styles/styles.scss b/app/styles/styles.scss index 7c58d6641..47557ef3c 100755 --- a/app/styles/styles.scss +++ b/app/styles/styles.scss @@ -39,6 +39,7 @@ $icon-font-path: '~bootstrap-sass/assets/fonts/bootstrap/'; @import 'views/statusbar'; @import 'views/tablelist'; @import 'views/tables'; +@import 'views/udfs'; @import 'views/views'; @import 'views/nodelist'; @import 'views/tutorial'; diff --git a/app/styles/views/_common.scss b/app/styles/views/_common.scss index 43fd9cfcd..7bbe24018 100644 --- a/app/styles/views/_common.scss +++ b/app/styles/views/_common.scss @@ -331,6 +331,8 @@ label:hover:before { border-radius: 3px; background: $cr-panel-default-background !important; font-family: $font-family-monospace; + white-space: pre; + word-break: normal; } .cr-cell--success{ diff --git a/app/styles/views/_udfs.scss b/app/styles/views/_udfs.scss new file mode 100644 index 000000000..6b16b2122 --- /dev/null +++ b/app/styles/views/_udfs.scss @@ -0,0 +1,60 @@ +.udf-detail { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + border: 1px solid $block-border; +} + +.udf-detail__row { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + width: 50%; +} + +.udf-detail__fullrow { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + width: 100%; +} + +.udf-detail.cr-panel-block { + margin-bottom: 5px !important; +} + +.udf-detail__cell { + width: 50%; + padding: 0px 15px; +} + +.udf-detail__fullcell { + width: 100%; + padding: 0px 15px; +} + +.udf-detail__cell-title { + font-weight: 700; +} + +.udf-detail__cell-content { + padding: 6px; + border-radius: 3px; + border: 1px solid $block-border; +} + +@media only screen and (max-width : $max-width-m) { + + .udf-detail__row { + width: 100%; + } + +} + +@media only screen and (max-width : $max-width-xs) { + + .udf-detail__cell { + width: 100%; + } + +} diff --git a/app/views/udf-detail.html b/app/views/udf-detail.html new file mode 100644 index 000000000..00168e5b7 --- /dev/null +++ b/app/views/udf-detail.html @@ -0,0 +1,61 @@ +
+
+ +

{{ 'NAVIGATION.UDF' | translate }}

+ +
+
+
+
+ {{ 'UDF.NAME' | translate }} +
+

+ {{ udf.label }} +

+
+
+
+ {{ 'UDF.PARAMETERS' | translate }} +
+

+ {{ udf.input_types }} +

+
+
+ +
+
+
+ {{ 'UDF.RETURN_TYPE' | translate }} +
+

+ {{ udf.return_type }} +

+
+
+
+ {{ 'UDF.LANGUAGE' | translate }} +
+

+ {{ udf.language }} +

+
+
+
+
+
+ {{ 'UDF.DEFINITION' | translate }} +
+

{{ udf.definition }}

+
+
+
+ +
+
+
{{ 'UDF.REPLACE_UDF' | translate }}
+
+
+ +
+
diff --git a/app/views/udflist.html b/app/views/udflist.html new file mode 100644 index 000000000..37dd525ce --- /dev/null +++ b/app/views/udflist.html @@ -0,0 +1,48 @@ + diff --git a/app/views/udfs.html b/app/views/udfs.html new file mode 100644 index 000000000..8bc95a40f --- /dev/null +++ b/app/views/udfs.html @@ -0,0 +1,15 @@ +
+
+
+

{{ 'UDF.TITLE' | translate }}

+
+

+ {{ 'UDF.VOID_MESSAGE' | translate }} + +

+
+
+ +
+ +
From 38ca6a2e0a9f3dafd99adb68c541cdf720ada10d Mon Sep 17 00:00:00 2001 From: Georg Traar Date: Tue, 26 Oct 2021 18:24:44 +0200 Subject: [PATCH 2/3] some fixes --- app/app.module.js | 4 +-- app/scripts/controllers/udfs.js | 50 ++++++++++++++------------------- app/static/i18n/en.json | 5 ++-- app/views/udflist.html | 4 +-- app/views/udfs.html | 2 +- 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/app/app.module.js b/app/app.module.js index aac1986d0..1897401ce 100644 --- a/app/app.module.js +++ b/app/app.module.js @@ -60,9 +60,9 @@ var ROUTING = { 'url': '/udfs', 'template': '', }, - '/udfs/:schema/:name': { + '/udfs/:schema/:name/:input_types': { 'name': 'udfs.udf', - 'url': '/:schema/:name', + 'url': '/:schema/:name/:input_types', 'template': '', }, '/views': { diff --git a/app/scripts/controllers/udfs.js b/app/scripts/controllers/udfs.js index 4559a5a24..e7de55c8e 100644 --- a/app/scripts/controllers/udfs.js +++ b/app/scripts/controllers/udfs.js @@ -53,17 +53,12 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) SQLQuery, queryResultToObjects, roundWithUnitFilter, bytesFilter, UdfList, ClusterEventsHandler, ClusterState) { - const NESTED_COL_REGEX = /([^\s]+)(\[\'([^\s]+)\'])+/i; - const COLUMNS_QUERY = 'SELECT quote_ident(column_name) as column_name, upper(data_type) AS column_type ' + - 'FROM information_schema.columns ' + - 'WHERE table_schema = ? AND table_name = ?'; - $scope.executeQuery = (query) => { $location.search({'query': query}); $location.path('/console'); }; - // sidebar button handler (mobile udf) + // sidebar button handler (mobile view) $scope.toggleSidebar = function () { $('#page-viewport') .toggleClass('show-sidebar'); @@ -77,43 +72,36 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) placement: 'top' }); - var isNestedColumn = (col) => col.match(NESTED_COL_REGEX); - - var constructQuery = (schema, name, rows) => { - var query = 'CREATE OR REPLACE FUNCTION "' + schema + '"."' + name + '"'; - query += '\nRETURNS '; - query += '\nLANGUAGE ' + 'JAVASCRIPT'; + var constructQuery = (schema, name, language) => { + var query = 'CREATE OR REPLACE FUNCTION "' + $scope.udf.schema + '"."' + $scope.udf.name + '"(' + $scope.udf.input_types +')'; + query += '\nRETURNS ' + $scope.udf.return_type; + query += '\nLANGUAGE ' + $scope.udf.language; query += '\nAS '; - query += '\n\'' + 'function'; + query += '\n\'' + $scope.udf.definition; query += '\n\';'; return query; }; - var render = (schema, name) => { + var render = (schema, name, input_types) => { $scope.nothingSelected = false; $scope.renderSiderbar = true; if (schema && name) { - SQLQuery.execute(COLUMNS_QUERY, [schema, name], false, false, false, false) - .then((q) => { - $scope.columns = queryResultToObjects(q, q.cols); - $scope.query = constructQuery(schema, name, $scope.columns); - }, () => { - $scope.columns = []; - }); + $scope.query = constructQuery(schema, name, input_types); } }; var updateUDF = () => { var name = $state.params.name; var schema = $state.params.schema; + var input_types = $state.params.input_types; var udfs = ClusterState.data.udfs; var hasUdfs = udfs.length > 0; $scope.renderSidebar = hasUdfs; $scope.nothingSelected = !hasUdfs; if (hasUdfs) { - var current = udfs.filter((o) => o.name == name && o.schema == schema); + var current = udfs.filter((o) => o.name == name && o.schema == schema && o.input_types == input_types); current = current.length ? current[0] : udfs[0]; $scope.udf = current; $scope.udf.label = current.schema + '.' + current.name; @@ -133,7 +121,7 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) }); updateUDF(); - render($state.params.schema, $state.params.name); + render($state.params.schema, $state.params.name, $state.params.input_types); } }; }) @@ -155,8 +143,8 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) $scope.search = ''; }; - $scope.isActive = (schema, name) => { - return name === $state.params.name && schema === $state.params.schema; + $scope.isActive = (schema, name, input_types) => { + return name === $state.params.name && schema === $state.params.schema && input_types === $state.params.input_types; }; var toggleClasses = (i) => { @@ -206,9 +194,11 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) if (!$scope.name || !$scope.schema) { $scope.schema = udfs[0].schema; $scope.name = udfs[0].name; + $scope.input_types = udfs[0].input_types; $state.go('udfs.udf', { schema: $scope.schema, - name: $scope.name + name: $scope.name, + input_types: $scope.input_types }); } @@ -233,15 +223,17 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) $scope.udfs.push({ display_name: name, udfs: udfs.filter(filterBySchemaName(name)), - schema: name + schema: name, + input_types : input_types }); } } }; - var render = (schema, name) => { + var render = (schema, name, input_types) => { $scope.name = name; $scope.schema = schema; + $scope.input_types = input_types; $scope.renderSidebar = true; }; @@ -254,7 +246,7 @@ angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events']) }); updateUdfList(); - render($state.params.schema, $state.params.name); + render($state.params.schema, $state.params.name, $state.params.input_types); } }; }); diff --git a/app/static/i18n/en.json b/app/static/i18n/en.json index f135955e4..0f7926fa2 100644 --- a/app/static/i18n/en.json +++ b/app/static/i18n/en.json @@ -104,9 +104,8 @@ }, "UDF": { "TITLE": "UDFs", - "VOID_MESSAGE": "There are no udfs created yet.", - "VOID_DETAILS": "Use the {{ statement }} statement to create new udfs.", - "QUERY_UDF": "Query udf", + "VOID_MESSAGE": "There are no UDFs created yet.", + "VOID_DETAILS": "Use the {{ statement }} statement to create new UDFs.", "REPLACE_UDF": "Replace UDF", "PARAMETERS": "Parameters", "RETURN_TYPE": "Return Type", diff --git a/app/views/udflist.html b/app/views/udflist.html index 37dd525ce..76ea4bbc6 100644 --- a/app/views/udflist.html +++ b/app/views/udflist.html @@ -1,7 +1,7 @@