summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 06:08:23 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 06:08:23 +0000
commitbe81c1578d65f25edfde8aa550f190b8d3e6d976 (patch)
tree0695fcaec3739d0ba486985bae2ebd85a3f49ee5 /app
parentbb19d18713d1b3da7d564826f5e21e8d9f9f36cd (diff)
downloadgitlab-ce-be81c1578d65f25edfde8aa550f190b8d3e6d976.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue61
-rw-r--r--app/assets/javascripts/clusters_list/constants.js11
-rw-r--r--app/assets/javascripts/clusters_list/index.js22
-rw-r--r--app/assets/javascripts/clusters_list/store/actions.js18
-rw-r--r--app/assets/javascripts/clusters_list/store/index.js16
-rw-r--r--app/assets/javascripts/clusters_list/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/clusters_list/store/mutations.js12
-rw-r--r--app/assets/javascripts/clusters_list/store/state.js19
-rw-r--r--app/assets/javascripts/pages/admin/clusters/index/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/clusters/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/clusters/index/index.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js1
-rw-r--r--app/serializers/merge_request_widget_entity.rb4
-rw-r--r--app/views/clusters/clusters/index.html.haml23
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"