diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-04 06:08:23 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-04 06:08:23 +0000 |
commit | be81c1578d65f25edfde8aa550f190b8d3e6d976 (patch) | |
tree | 0695fcaec3739d0ba486985bae2ebd85a3f49ee5 /app | |
parent | bb19d18713d1b3da7d564826f5e21e8d9f9f36cd (diff) | |
download | gitlab-ce-be81c1578d65f25edfde8aa550f190b8d3e6d976.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
14 files changed, 185 insertions, 10 deletions
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue new file mode 100644 index 00000000000..9322423370b --- /dev/null +++ b/app/assets/javascripts/clusters_list/components/clusters.vue @@ -0,0 +1,61 @@ +<script> +import { mapState, mapActions } from 'vuex'; +import { GlTable, GlLoadingIcon, GlBadge } from '@gitlab/ui'; +import { CLUSTER_TYPES } from '../constants'; +import { __ } from '~/locale'; + +export default { + components: { + GlTable, + GlLoadingIcon, + GlBadge, + }, + fields: [ + { + key: 'name', + label: __('Kubernetes cluster'), + }, + { + key: 'environmentScope', + label: __('Environment scope'), + }, + { + key: 'size', + label: __('Size'), + }, + { + key: 'clusterType', + label: __('Cluster level'), + formatter: value => CLUSTER_TYPES[value], + }, + ], + computed: { + ...mapState(['clusters', 'loading']), + }, + mounted() { + // TODO - uncomment this once integrated with BE + // this.fetchClusters(); + }, + methods: { + ...mapActions(['fetchClusters']), + }, +}; +</script> + +<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(clusterType)="{value}"> + <gl-badge variant="light"> + {{ value }} + </gl-badge> + </template> + </gl-table> +</template> diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js new file mode 100644 index 00000000000..4125288b5a5 --- /dev/null +++ b/app/assets/javascripts/clusters_list/constants.js @@ -0,0 +1,11 @@ +import { __ } from '~/locale'; + +export const CLUSTER_TYPES = { + project_type: __('Project'), + group_type: __('Group'), + instance_type: __('Instance'), +}; + +export default { + CLUSTER_TYPES, +}; diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js new file mode 100644 index 00000000000..67d0a33030b --- /dev/null +++ b/app/assets/javascripts/clusters_list/index.js @@ -0,0 +1,22 @@ +import Vue from 'vue'; +import Clusters from './components/clusters.vue'; +import { createStore } from './store'; + +export default () => { + const entryPoint = document.querySelector('#js-clusters-list-app'); + + if (!entryPoint) { + return; + } + + const { endpoint } = entryPoint.dataset; + + // eslint-disable-next-line no-new + new Vue({ + el: '#js-clusters-list-app', + store: createStore({ endpoint }), + render(createElement) { + return createElement(Clusters); + }, + }); +}; diff --git a/app/assets/javascripts/clusters_list/store/actions.js b/app/assets/javascripts/clusters_list/store/actions.js new file mode 100644 index 00000000000..39fd9fdf625 --- /dev/null +++ b/app/assets/javascripts/clusters_list/store/actions.js @@ -0,0 +1,18 @@ +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import axios from '~/lib/utils/axios_utils'; +import flash from '~/flash'; +import { __ } from '~/locale'; +import * as types from './mutation_types'; + +export const fetchClusters = ({ state, commit }) => { + return axios + .get(state.endpoint) + .then(({ data }) => { + commit(types.SET_CLUSTERS_DATA, convertObjectPropsToCamelCase(data, { deep: true })); + commit(types.SET_LOADING_STATE, false); + }) + .catch(() => flash(__('An error occurred while loading clusters'))); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/clusters_list/store/index.js b/app/assets/javascripts/clusters_list/store/index.js new file mode 100644 index 00000000000..c472d2f354c --- /dev/null +++ b/app/assets/javascripts/clusters_list/store/index.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import state from './state'; +import mutations from './mutations'; +import * as actions from './actions'; + +Vue.use(Vuex); + +export const createStore = initialState => + new Vuex.Store({ + actions, + mutations, + state: state(initialState), + }); + +export default createStore; diff --git a/app/assets/javascripts/clusters_list/store/mutation_types.js b/app/assets/javascripts/clusters_list/store/mutation_types.js new file mode 100644 index 00000000000..f056f3ab7d9 --- /dev/null +++ b/app/assets/javascripts/clusters_list/store/mutation_types.js @@ -0,0 +1,2 @@ +export const SET_CLUSTERS_DATA = 'SET_CLUSTERS_DATA'; +export const SET_LOADING_STATE = 'SET_LOADING_STATE'; diff --git a/app/assets/javascripts/clusters_list/store/mutations.js b/app/assets/javascripts/clusters_list/store/mutations.js new file mode 100644 index 00000000000..ffd3c4601bf --- /dev/null +++ b/app/assets/javascripts/clusters_list/store/mutations.js @@ -0,0 +1,12 @@ +import * as types from './mutation_types'; + +export default { + [types.SET_LOADING_STATE](state, value) { + state.loading = value; + }, + [types.SET_CLUSTERS_DATA](state, clusters) { + Object.assign(state, { + clusters, + }); + }, +}; diff --git a/app/assets/javascripts/clusters_list/store/state.js b/app/assets/javascripts/clusters_list/store/state.js new file mode 100644 index 00000000000..e6cdf9d67db --- /dev/null +++ b/app/assets/javascripts/clusters_list/store/state.js @@ -0,0 +1,19 @@ +export default (initialState = {}) => ({ + endpoint: initialState.endpoint, + loading: false, // TODO - set this to true once integrated with BE + clusters: [ + // TODO - remove mock data once integrated with BE + // { + // name: 'My Cluster', + // environmentScope: '*', + // size: '3', + // clusterType: 'group_type', + // }, + // { + // name: 'My other cluster', + // environmentScope: 'production', + // size: '12', + // clusterType: 'project_type', + // }, + ], +}); diff --git a/app/assets/javascripts/pages/admin/clusters/index/index.js b/app/assets/javascripts/pages/admin/clusters/index/index.js index 30d519d0e37..744be65bfbe 100644 --- a/app/assets/javascripts/pages/admin/clusters/index/index.js +++ b/app/assets/javascripts/pages/admin/clusters/index/index.js @@ -1,6 +1,8 @@ import PersistentUserCallout from '~/persistent_user_callout'; +import initClustersListApp from '~/clusters_list'; document.addEventListener('DOMContentLoaded', () => { const callout = document.querySelector('.gcp-signup-offer'); PersistentUserCallout.factory(callout); + initClustersListApp(); }); diff --git a/app/assets/javascripts/pages/groups/clusters/index/index.js b/app/assets/javascripts/pages/groups/clusters/index/index.js index 30d519d0e37..744be65bfbe 100644 --- a/app/assets/javascripts/pages/groups/clusters/index/index.js +++ b/app/assets/javascripts/pages/groups/clusters/index/index.js @@ -1,6 +1,8 @@ import PersistentUserCallout from '~/persistent_user_callout'; +import initClustersListApp from '~/clusters_list'; document.addEventListener('DOMContentLoaded', () => { const callout = document.querySelector('.gcp-signup-offer'); PersistentUserCallout.factory(callout); + initClustersListApp(); }); diff --git a/app/assets/javascripts/pages/projects/clusters/index/index.js b/app/assets/javascripts/pages/projects/clusters/index/index.js index 30d519d0e37..744be65bfbe 100644 --- a/app/assets/javascripts/pages/projects/clusters/index/index.js +++ b/app/assets/javascripts/pages/projects/clusters/index/index.js @@ -1,6 +1,8 @@ import PersistentUserCallout from '~/persistent_user_callout'; +import initClustersListApp from '~/clusters_list'; document.addEventListener('DOMContentLoaded', () => { const callout = document.querySelector('.gcp-signup-offer'); PersistentUserCallout.factory(callout); + initClustersListApp(); }); diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index 91ac23f427d..2aecd0938e4 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -180,6 +180,7 @@ export default class MergeRequestStore { this.mergeRequestAddCiConfigPath = data.merge_request_add_ci_config_path; this.pipelinesEmptySvgPath = data.pipelines_empty_svg_path; this.humanAccess = data.human_access; + this.newPipelinePath = data.new_project_pipeline_path; } get isNothingToMergeState() { diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb index 6df26de529d..7ba15dd9acf 100644 --- a/app/serializers/merge_request_widget_entity.rb +++ b/app/serializers/merge_request_widget_entity.rb @@ -64,6 +64,10 @@ class MergeRequestWidgetEntity < Grape::Entity merge_request.project.team.human_max_access(current_user&.id) end + expose :new_project_pipeline_path do |merge_request| + new_project_pipeline_path(merge_request.project) + end + # Rendering and redacting Markdown can be expensive. These links are # just nice to have in the merge request widget, so only # include them if they are explicitly requested on first load. diff --git a/app/views/clusters/clusters/index.html.haml b/app/views/clusters/clusters/index.html.haml index 049010cadf4..28002dbff92 100644 --- a/app/views/clusters/clusters/index.html.haml +++ b/app/views/clusters/clusters/index.html.haml @@ -18,13 +18,16 @@ %strong = link_to _('More information'), help_page_path('user/group/clusters/index', anchor: 'cluster-precedence') - .clusters-table.js-clusters-list - .gl-responsive-table-row.table-row-header{ role: "row" } - .table-section.section-60{ role: "rowheader" } - = s_("ClusterIntegration|Kubernetes cluster") - .table-section.section-30{ role: "rowheader" } - = s_("ClusterIntegration|Environment scope") - .table-section.section-10{ role: "rowheader" } - - @clusters.each do |cluster| - = render "cluster", cluster: cluster.present(current_user: current_user) - = paginate @clusters, theme: "gitlab" + - if Feature.enabled?(:clusters_list_redesign) + #js-clusters-list-app{ data: { endpoint: 'todo/add/endpoint' } } + - else + .clusters-table.js-clusters-list + .gl-responsive-table-row.table-row-header{ role: "row" } + .table-section.section-60{ role: "rowheader" } + = s_("ClusterIntegration|Kubernetes cluster") + .table-section.section-30{ role: "rowheader" } + = s_("ClusterIntegration|Environment scope") + .table-section.section-10{ role: "rowheader" } + - @clusters.each do |cluster| + = render "cluster", cluster: cluster.present(current_user: current_user) + = paginate @clusters, theme: "gitlab" |