From 2c80a1c0de07877e6e2bf7ab20de2d4f43a0d97c Mon Sep 17 00:00:00 2001 From: Dylan Griffith Date: Thu, 6 Dec 2018 18:08:49 +0000 Subject: Introduce Knative Serverless Tab --- .../serverless/components/empty_state.vue | 40 +++++++ .../serverless/components/function_row.vue | 40 +++++++ .../serverless/components/functions.vue | 123 +++++++++++++++++++++ app/assets/javascripts/serverless/event_hub.js | 3 + .../javascripts/serverless/serverless_bundle.js | 106 ++++++++++++++++++ .../serverless/services/get_functions_service.js | 11 ++ .../serverless/stores/serverless_store.js | 24 ++++ 7 files changed, 347 insertions(+) create mode 100644 app/assets/javascripts/serverless/components/empty_state.vue create mode 100644 app/assets/javascripts/serverless/components/function_row.vue create mode 100644 app/assets/javascripts/serverless/components/functions.vue create mode 100644 app/assets/javascripts/serverless/event_hub.js create mode 100644 app/assets/javascripts/serverless/serverless_bundle.js create mode 100644 app/assets/javascripts/serverless/services/get_functions_service.js create mode 100644 app/assets/javascripts/serverless/stores/serverless_store.js (limited to 'app/assets/javascripts/serverless') diff --git a/app/assets/javascripts/serverless/components/empty_state.vue b/app/assets/javascripts/serverless/components/empty_state.vue new file mode 100644 index 00000000000..2683805f2f7 --- /dev/null +++ b/app/assets/javascripts/serverless/components/empty_state.vue @@ -0,0 +1,40 @@ + + + diff --git a/app/assets/javascripts/serverless/components/function_row.vue b/app/assets/javascripts/serverless/components/function_row.vue new file mode 100644 index 00000000000..31f5427c771 --- /dev/null +++ b/app/assets/javascripts/serverless/components/function_row.vue @@ -0,0 +1,40 @@ + + + diff --git a/app/assets/javascripts/serverless/components/functions.vue b/app/assets/javascripts/serverless/components/functions.vue new file mode 100644 index 00000000000..7874a7b6b6a --- /dev/null +++ b/app/assets/javascripts/serverless/components/functions.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/app/assets/javascripts/serverless/event_hub.js b/app/assets/javascripts/serverless/event_hub.js new file mode 100644 index 00000000000..0948c2e5352 --- /dev/null +++ b/app/assets/javascripts/serverless/event_hub.js @@ -0,0 +1,3 @@ +import Vue from 'vue'; + +export default new Vue(); diff --git a/app/assets/javascripts/serverless/serverless_bundle.js b/app/assets/javascripts/serverless/serverless_bundle.js new file mode 100644 index 00000000000..3e3b81ba247 --- /dev/null +++ b/app/assets/javascripts/serverless/serverless_bundle.js @@ -0,0 +1,106 @@ +import Visibility from 'visibilityjs'; +import Vue from 'vue'; +import { s__ } from '../locale'; +import Flash from '../flash'; +import Poll from '../lib/utils/poll'; +import ServerlessStore from './stores/serverless_store'; +import GetFunctionsService from './services/get_functions_service'; +import Functions from './components/functions.vue'; + +export default class Serverless { + constructor() { + const { statusPath, clustersPath, helpPath, installed } = document.querySelector( + '.js-serverless-functions-page', + ).dataset; + + this.service = new GetFunctionsService(statusPath); + this.knativeInstalled = installed !== undefined; + this.store = new ServerlessStore(this.knativeInstalled, clustersPath, helpPath); + this.initServerless(); + this.functionLoadCount = 0; + + if (statusPath && this.knativeInstalled) { + this.initPolling(); + } + } + + initServerless() { + const { store } = this; + const el = document.querySelector('#js-serverless-functions'); + + this.functions = new Vue({ + el, + data() { + return { + state: store.state, + }; + }, + render(createElement) { + return createElement(Functions, { + props: { + functions: this.state.functions, + installed: this.state.installed, + clustersPath: this.state.clustersPath, + helpPath: this.state.helpPath, + loadingData: this.state.loadingData, + hasFunctionData: this.state.hasFunctionData, + }, + }); + }, + }); + } + + initPolling() { + this.poll = new Poll({ + resource: this.service, + method: 'fetchData', + successCallback: data => this.handleSuccess(data), + errorCallback: () => this.handleError(), + }); + + if (!Visibility.hidden()) { + this.poll.makeRequest(); + } else { + this.service + .fetchData() + .then(data => this.handleSuccess(data)) + .catch(() => this.handleError()); + } + + Visibility.change(() => { + if (!Visibility.hidden() && !this.destroyed) { + this.poll.restart(); + } else { + this.poll.stop(); + } + }); + } + + handleSuccess(data) { + if (data.status === 200) { + this.store.updateFunctionsFromServer(data.data); + this.store.updateLoadingState(false); + } else if (data.status === 204) { + /* Time out after 3 attempts to retrieve data */ + this.functionLoadCount += 1; + if (this.functionLoadCount === 3) { + this.poll.stop(); + this.store.toggleNoFunctionData(); + } + } + } + + static handleError() { + Flash(s__('Serverless|An error occurred while retrieving serverless components')); + } + + destroy() { + this.destroyed = true; + + if (this.poll) { + this.poll.stop(); + } + + this.functions.$destroy(); + } +} diff --git a/app/assets/javascripts/serverless/services/get_functions_service.js b/app/assets/javascripts/serverless/services/get_functions_service.js new file mode 100644 index 00000000000..303b42dc66c --- /dev/null +++ b/app/assets/javascripts/serverless/services/get_functions_service.js @@ -0,0 +1,11 @@ +import axios from '~/lib/utils/axios_utils'; + +export default class GetFunctionsService { + constructor(endpoint) { + this.endpoint = endpoint; + } + + fetchData() { + return axios.get(this.endpoint); + } +} diff --git a/app/assets/javascripts/serverless/stores/serverless_store.js b/app/assets/javascripts/serverless/stores/serverless_store.js new file mode 100644 index 00000000000..774c15b5b12 --- /dev/null +++ b/app/assets/javascripts/serverless/stores/serverless_store.js @@ -0,0 +1,24 @@ +export default class ServerlessStore { + constructor(knativeInstalled = false, clustersPath, helpPath) { + this.state = { + functions: [], + hasFunctionData: true, + loadingData: true, + installed: knativeInstalled, + clustersPath, + helpPath, + }; + } + + updateFunctionsFromServer(functions = []) { + this.state.functions = functions; + } + + updateLoadingState(loadingData) { + this.state.loadingData = loadingData; + } + + toggleNoFunctionData() { + this.state.hasFunctionData = false; + } +} -- cgit v1.2.1