diff options
Diffstat (limited to 'app/assets/javascripts/clusters_list')
6 files changed, 126 insertions, 89 deletions
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue index 46dacf30f39..af3f1437c64 100644 --- a/app/assets/javascripts/clusters_list/components/clusters.vue +++ b/app/assets/javascripts/clusters_list/components/clusters.vue @@ -1,61 +1,78 @@ <script> import { mapState, mapActions } from 'vuex'; -import { GlTable, GlLoadingIcon, GlBadge } from '@gitlab/ui'; +import { GlBadge, GlLink, GlLoadingIcon, GlPagination, GlTable } from '@gitlab/ui'; import tooltip from '~/vue_shared/directives/tooltip'; import { CLUSTER_TYPES, STATUSES } from '../constants'; import { __, sprintf } from '~/locale'; export default { components: { - GlTable, - GlLoadingIcon, GlBadge, + GlLink, + GlLoadingIcon, + GlPagination, + GlTable, }, directives: { tooltip, }, - fields: [ - { - key: 'name', - label: __('Kubernetes cluster'), - }, - { - key: 'environmentScope', - label: __('Environment scope'), - }, - { - key: 'size', - label: __('Size'), - }, - { - key: 'cpu', - label: __('Total cores (vCPUs)'), + computed: { + ...mapState(['clusters', 'clustersPerPage', 'loading', 'page', 'totalCulsters']), + currentPage: { + get() { + return this.page; + }, + set(newVal) { + this.setPage(newVal); + this.fetchClusters(); + }, }, - { - key: 'memory', - label: __('Total memory (GB)'), + fields() { + return [ + { + key: 'name', + label: __('Kubernetes cluster'), + }, + { + key: 'environment_scope', + label: __('Environment scope'), + }, + // Wait for backend to send these fields + // { + // key: 'size', + // label: __('Size'), + // }, + // { + // key: 'cpu', + // label: __('Total cores (vCPUs)'), + // }, + // { + // key: 'memory', + // label: __('Total memory (GB)'), + // }, + { + key: 'cluster_type', + label: __('Cluster level'), + formatter: value => CLUSTER_TYPES[value], + }, + ]; }, - { - key: 'clusterType', - label: __('Cluster level'), - formatter: value => CLUSTER_TYPES[value], + hasClusters() { + return this.clustersPerPage > 0; }, - ], - computed: { - ...mapState(['clusters', 'loading']), }, mounted() { - // TODO - uncomment this once integrated with BE - // this.fetchClusters(); + this.fetchClusters(); }, methods: { - ...mapActions(['fetchClusters']), + ...mapActions(['fetchClusters', 'setPage']), statusClass(status) { - return STATUSES[status].className; + const iconClass = STATUSES[status] || STATUSES.default; + return iconClass.className; }, statusTitle(status) { - const { title } = STATUSES[status]; - return sprintf(__('Status: %{title}'), { title }, false); + const iconTitle = STATUSES[status] || STATUSES.default; + return sprintf(__('Status: %{title}'), { title: iconTitle.title }, false); }, }, }; @@ -63,37 +80,46 @@ export default { <template> <gl-loading-icon v-if="loading" size="md" class="mt-3" /> - <gl-table - v-else - :items="clusters" - :fields="$options.fields" - stacked="md" - variant="light" - class="qa-clusters-table" - > - <template #cell(name)="{ item }"> - <div class="d-flex flex-row-reverse flex-md-row js-status"> - {{ item.name }} - <gl-loading-icon - v-if="item.status === 'deleting'" - v-tooltip - :title="statusTitle(item.status)" - size="sm" - class="mr-2 ml-md-2" - /> - <div - v-else - v-tooltip - class="cluster-status-indicator rounded-circle align-self-center gl-w-8 gl-h-8 mr-2 ml-md-2" - :class="statusClass(item.status)" - :title="statusTitle(item.status)" - ></div> - </div> - </template> - <template #cell(clusterType)="{value}"> - <gl-badge variant="light"> - {{ value }} - </gl-badge> - </template> - </gl-table> + + <section v-else> + <gl-table :items="clusters" :fields="fields" stacked="md" class="qa-clusters-table"> + <template #cell(name)="{ item }"> + <div class="d-flex flex-row-reverse flex-md-row js-status"> + <gl-link data-qa-selector="cluster" :data-qa-cluster-name="item.name" :href="item.path"> + {{ item.name }} + </gl-link> + + <gl-loading-icon + v-if="item.status === 'deleting'" + v-tooltip + :title="statusTitle(item.status)" + size="sm" + class="mr-2 ml-md-2" + /> + <div + v-else + v-tooltip + class="cluster-status-indicator rounded-circle align-self-center gl-w-4 gl-h-4 mr-2 ml-md-2" + :class="statusClass(item.status)" + :title="statusTitle(item.status)" + ></div> + </div> + </template> + <template #cell(cluster_type)="{value}"> + <gl-badge variant="light"> + {{ value }} + </gl-badge> + </template> + </gl-table> + + <gl-pagination + v-if="hasClusters" + v-model="currentPage" + :per-page="clustersPerPage" + :total-items="totalCulsters" + :prev-text="__('Prev')" + :next-text="__('Next')" + align="center" + /> + </section> </template> diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js index 9428f08176c..eebcaa086f9 100644 --- a/app/assets/javascripts/clusters_list/constants.js +++ b/app/assets/javascripts/clusters_list/constants.js @@ -7,8 +7,9 @@ export const CLUSTER_TYPES = { }; export const STATUSES = { + default: { className: 'bg-white', title: __('Unknown') }, disabled: { className: 'disabled', title: __('Disabled') }, - connected: { className: 'bg-success', title: __('Connected') }, + created: { className: 'bg-success', title: __('Connected') }, unreachable: { className: 'bg-danger', title: __('Unreachable') }, authentication_failure: { className: 'bg-warning', title: __('Authentication Failure') }, deleting: { title: __('Deleting') }, diff --git a/app/assets/javascripts/clusters_list/store/actions.js b/app/assets/javascripts/clusters_list/store/actions.js index 79bc9932438..919625f69b4 100644 --- a/app/assets/javascripts/clusters_list/store/actions.js +++ b/app/assets/javascripts/clusters_list/store/actions.js @@ -1,36 +1,35 @@ -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import Poll from '~/lib/utils/poll'; import axios from '~/lib/utils/axios_utils'; -import Visibility from 'visibilityjs'; import flash from '~/flash'; import { __ } from '~/locale'; +import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; import * as types from './mutation_types'; export const fetchClusters = ({ state, commit }) => { const poll = new Poll({ resource: { - fetchClusters: endpoint => axios.get(endpoint), + fetchClusters: paginatedEndPoint => axios.get(paginatedEndPoint), }, - data: state.endpoint, + data: `${state.endpoint}?page=${state.page}`, method: 'fetchClusters', - successCallback: ({ data }) => { - commit(types.SET_CLUSTERS_DATA, convertObjectPropsToCamelCase(data, { deep: true })); - commit(types.SET_LOADING_STATE, false); + successCallback: ({ data, headers }) => { + if (data.clusters) { + const normalizedHeaders = normalizeHeaders(headers); + const paginationInformation = parseIntPagination(normalizedHeaders); + + commit(types.SET_CLUSTERS_DATA, { data, paginationInformation }); + commit(types.SET_LOADING_STATE, false); + poll.stop(); + } }, errorCallback: () => flash(__('An error occurred while loading clusters')), }); - if (!Visibility.hidden()) { - poll.makeRequest(); - } + poll.makeRequest(); +}; - Visibility.change(() => { - if (!Visibility.hidden()) { - poll.restart(); - } else { - poll.stop(); - } - }); +export const setPage = ({ commit }, page) => { + commit(types.SET_PAGE, page); }; // prevent babel-plugin-rewire from generating an invalid default during karma tests diff --git a/app/assets/javascripts/clusters_list/store/mutation_types.js b/app/assets/javascripts/clusters_list/store/mutation_types.js index f056f3ab7d9..a5275f28c13 100644 --- a/app/assets/javascripts/clusters_list/store/mutation_types.js +++ b/app/assets/javascripts/clusters_list/store/mutation_types.js @@ -1,2 +1,3 @@ export const SET_CLUSTERS_DATA = 'SET_CLUSTERS_DATA'; export const SET_LOADING_STATE = 'SET_LOADING_STATE'; +export const SET_PAGE = 'SET_PAGE'; diff --git a/app/assets/javascripts/clusters_list/store/mutations.js b/app/assets/javascripts/clusters_list/store/mutations.js index ffd3c4601bf..2a9df9f38f0 100644 --- a/app/assets/javascripts/clusters_list/store/mutations.js +++ b/app/assets/javascripts/clusters_list/store/mutations.js @@ -4,9 +4,15 @@ export default { [types.SET_LOADING_STATE](state, value) { state.loading = value; }, - [types.SET_CLUSTERS_DATA](state, clusters) { + [types.SET_CLUSTERS_DATA](state, { data, paginationInformation }) { Object.assign(state, { - clusters, + clusters: data.clusters, + clustersPerPage: paginationInformation.perPage, + hasAncestorClusters: data.has_ancestor_clusters, + totalCulsters: paginationInformation.total, }); }, + [types.SET_PAGE](state, value) { + state.page = Number(value) || 1; + }, }; diff --git a/app/assets/javascripts/clusters_list/store/state.js b/app/assets/javascripts/clusters_list/store/state.js index ed032ed8435..d590ea09e66 100644 --- a/app/assets/javascripts/clusters_list/store/state.js +++ b/app/assets/javascripts/clusters_list/store/state.js @@ -1,5 +1,9 @@ export default (initialState = {}) => ({ endpoint: initialState.endpoint, - loading: false, // TODO - set this to true once integrated with BE + hasAncestorClusters: false, + loading: true, clusters: [], + clustersPerPage: 0, + page: 1, + totalCulsters: 0, }); |