Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-30 12:09:39 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-30 12:09:39 +0300
commitada214dc52b53bd9eb3a79c279506f91c547f721 (patch)
treef4266ef83f9be3a62a0f8942911058758655929a /app/assets
parent27b43bd4d613cc7b8773ca0863b8d8f9b90f6d87 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/boards/constants.js6
-rw-r--r--app/assets/javascripts/boards/index.js110
-rw-r--r--app/assets/javascripts/boards/models/assignee.js2
-rw-r--r--app/assets/javascripts/boards/models/issue.js2
-rw-r--r--app/assets/javascripts/boards/models/list.js12
-rw-r--r--app/assets/javascripts/boards/queries/board_list.fragment.graphql5
-rw-r--r--app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql15
-rw-r--r--app/assets/javascripts/boards/queries/group_board.query.graphql13
-rw-r--r--app/assets/javascripts/boards/queries/project_board.query.graphql13
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js10
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue33
-rw-r--r--app/assets/javascripts/environments/mixins/environments_app_mixin.js32
-rw-r--r--app/assets/javascripts/environments/stores/environments_store.js11
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue20
-rw-r--r--app/assets/stylesheets/framework/common.scss1
15 files changed, 202 insertions, 83 deletions
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 40f79a44b51..f577a168e75 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -1,3 +1,8 @@
+export const BoardType = {
+ project: 'project',
+ group: 'group',
+};
+
export const ListType = {
assignee: 'assignee',
milestone: 'milestone',
@@ -11,5 +16,6 @@ export const ListType = {
export const inactiveListId = 0;
export default {
+ BoardType,
ListType,
};
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index a12db7a5f1a..7c41182d554 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -16,10 +16,13 @@ import {
getBoardsModalData,
} from 'ee_else_ce/boards/ee_functions';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
import Flash from '~/flash';
import { __ } from '~/locale';
import './models/label';
import './models/assignee';
+import { BoardType } from './constants';
import FilteredSearchBoards from '~/boards/filtered_search_boards';
import eventHub from '~/boards/eventhub';
@@ -37,7 +40,16 @@ import {
convertObjectPropsToCamelCase,
parseBoolean,
} from '~/lib/utils/common_utils';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
+import projectBoardQuery from './queries/project_board.query.graphql';
+import groupQuery from './queries/group_board.query.graphql';
+
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
let issueBoardsApp;
@@ -79,18 +91,22 @@ export default () => {
import('ee_component/boards/components/board_settings_sidebar.vue'),
},
store,
- data: {
- state: boardsStore.state,
- loading: true,
- boardsEndpoint: $boardApp.dataset.boardsEndpoint,
- recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
- listsEndpoint: $boardApp.dataset.listsEndpoint,
- boardId: $boardApp.dataset.boardId,
- disabled: parseBoolean($boardApp.dataset.disabled),
- issueLinkBase: $boardApp.dataset.issueLinkBase,
- rootPath: $boardApp.dataset.rootPath,
- bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
- detailIssue: boardsStore.detail,
+ apolloProvider,
+ data() {
+ return {
+ state: boardsStore.state,
+ loading: 0,
+ boardsEndpoint: $boardApp.dataset.boardsEndpoint,
+ recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint,
+ listsEndpoint: $boardApp.dataset.listsEndpoint,
+ boardId: $boardApp.dataset.boardId,
+ disabled: parseBoolean($boardApp.dataset.disabled),
+ issueLinkBase: $boardApp.dataset.issueLinkBase,
+ rootPath: $boardApp.dataset.rootPath,
+ bulkUpdatePath: $boardApp.dataset.bulkUpdatePath,
+ detailIssue: boardsStore.detail,
+ parent: $boardApp.dataset.parent,
+ };
},
computed: {
detailIssueVisible() {
@@ -124,31 +140,56 @@ export default () => {
this.filterManager.setup();
boardsStore.disabled = this.disabled;
- boardsStore
- .all()
- .then(res => res.data)
- .then(lists => {
- lists.forEach(listObj => {
- let { position } = listObj;
- if (listObj.list_type === 'closed') {
- position = Infinity;
- } else if (listObj.list_type === 'backlog') {
- position = -1;
+
+ if (gon.features.graphqlBoardLists) {
+ this.$apollo.addSmartQuery('lists', {
+ query() {
+ return this.parent === BoardType.group ? groupQuery : projectBoardQuery;
+ },
+ variables() {
+ return {
+ fullPath: this.state.endpoints.fullPath,
+ boardId: `gid://gitlab/Board/${this.boardId}`,
+ };
+ },
+ update(data) {
+ return this.getNodes(data);
+ },
+ result({ data, error }) {
+ if (error) {
+ throw error;
}
- boardsStore.addList({
- ...listObj,
- position,
- });
- });
+ const lists = this.getNodes(data);
+
+ lists.forEach(list =>
+ boardsStore.addList({
+ ...list,
+ id: getIdFromGraphQLId(list.id),
+ }),
+ );
- boardsStore.addBlankState();
- setPromotionState(boardsStore);
- this.loading = false;
- })
- .catch(() => {
- Flash(__('An error occurred while fetching the board lists. Please try again.'));
+ boardsStore.addBlankState();
+ setPromotionState(boardsStore);
+ },
+ error() {
+ Flash(__('An error occurred while fetching the board lists. Please try again.'));
+ },
});
+ } else {
+ boardsStore
+ .all()
+ .then(res => res.data)
+ .then(lists => {
+ lists.forEach(list => boardsStore.addList(list));
+ boardsStore.addBlankState();
+ setPromotionState(boardsStore);
+ this.loading = false;
+ })
+ .catch(() => {
+ Flash(__('An error occurred while fetching the board lists. Please try again.'));
+ });
+ }
},
methods: {
updateTokens() {
@@ -233,6 +274,9 @@ export default () => {
});
}
},
+ getNodes(data) {
+ return data[this.parent]?.board?.lists.nodes;
+ },
},
});
diff --git a/app/assets/javascripts/boards/models/assignee.js b/app/assets/javascripts/boards/models/assignee.js
index 5f5758583bb..1e822d06bfd 100644
--- a/app/assets/javascripts/boards/models/assignee.js
+++ b/app/assets/javascripts/boards/models/assignee.js
@@ -3,7 +3,7 @@ export default class ListAssignee {
this.id = obj.id;
this.name = obj.name;
this.username = obj.username;
- this.avatar = obj.avatar_url || obj.avatar || gon.default_avatar_url;
+ this.avatar = obj.avatarUrl || obj.avatar_url || obj.avatar || gon.default_avatar_url;
this.path = obj.path;
this.state = obj.state;
this.webUrl = obj.web_url || obj.webUrl;
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index af1a910149e..878f49cc6be 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -15,7 +15,7 @@ class ListIssue {
this.labels = [];
this.assignees = [];
this.selected = false;
- this.position = obj.relative_position || Infinity;
+ this.position = obj.position || obj.relative_position || Infinity;
this.isFetching = {
subscriptions: true,
};
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
index cd46f8cd1a4..31c372b7a75 100644
--- a/app/assets/javascripts/boards/models/list.js
+++ b/app/assets/javascripts/boards/models/list.js
@@ -39,8 +39,8 @@ class List {
this.id = obj.id;
this._uid = this.guid();
this.position = obj.position;
- this.title = obj.list_type === 'backlog' ? __('Open') : obj.title;
- this.type = obj.list_type;
+ this.title = (obj.list_type || obj.listType) === 'backlog' ? __('Open') : obj.title;
+ this.type = obj.list_type || obj.listType;
const typeInfo = this.getTypeInfo(this.type);
this.preset = Boolean(typeInfo.isPreset);
@@ -51,14 +51,12 @@ class List {
this.loadingMore = false;
this.issues = obj.issues || [];
this.issuesSize = obj.issuesSize ? obj.issuesSize : 0;
- this.maxIssueCount = Object.hasOwnProperty.call(obj, 'max_issue_count')
- ? obj.max_issue_count
- : 0;
+ this.maxIssueCount = obj.maxIssueCount || obj.max_issue_count || 0;
if (obj.label) {
this.label = new ListLabel(obj.label);
- } else if (obj.user) {
- this.assignee = new ListAssignee(obj.user);
+ } else if (obj.user || obj.assignee) {
+ this.assignee = new ListAssignee(obj.user || obj.assignee);
this.title = this.assignee.name;
} else if (IS_EE && obj.milestone) {
this.milestone = new ListMilestone(obj.milestone);
diff --git a/app/assets/javascripts/boards/queries/board_list.fragment.graphql b/app/assets/javascripts/boards/queries/board_list.fragment.graphql
new file mode 100644
index 00000000000..bbf3314377e
--- /dev/null
+++ b/app/assets/javascripts/boards/queries/board_list.fragment.graphql
@@ -0,0 +1,5 @@
+#import "./board_list_shared.fragment.graphql"
+
+fragment BoardListFragment on BoardList {
+ ...BoardListShared
+}
diff --git a/app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql b/app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql
new file mode 100644
index 00000000000..6ba6c05d6d9
--- /dev/null
+++ b/app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql
@@ -0,0 +1,15 @@
+fragment BoardListShared on BoardList {
+ id,
+ title,
+ position,
+ listType,
+ collapsed,
+ label {
+ id,
+ title,
+ color,
+ textColor,
+ description,
+ descriptionHtml
+ }
+}
diff --git a/app/assets/javascripts/boards/queries/group_board.query.graphql b/app/assets/javascripts/boards/queries/group_board.query.graphql
new file mode 100644
index 00000000000..cb42cb3f73d
--- /dev/null
+++ b/app/assets/javascripts/boards/queries/group_board.query.graphql
@@ -0,0 +1,13 @@
+#import "ee_else_ce/boards/queries/board_list.fragment.graphql"
+
+query GroupBoard($fullPath: ID!, $boardId: ID!) {
+ group(fullPath: $fullPath) {
+ board(id: $boardId) {
+ lists {
+ nodes {
+ ...BoardListFragment
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/boards/queries/project_board.query.graphql b/app/assets/javascripts/boards/queries/project_board.query.graphql
new file mode 100644
index 00000000000..4620a7e0fd5
--- /dev/null
+++ b/app/assets/javascripts/boards/queries/project_board.query.graphql
@@ -0,0 +1,13 @@
+#import "ee_else_ce/boards/queries/board_list.fragment.graphql"
+
+query ProjectBoard($fullPath: ID!, $boardId: ID!) {
+ project(fullPath: $fullPath) {
+ board(id: $boardId) {
+ lists {
+ nodes {
+ ...BoardListFragment
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index d20b99ecfaa..b8ae6396475 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -80,7 +80,15 @@ const boardsStore = {
this.state.currentPage = page;
},
addList(listObj) {
- const list = new List(listObj);
+ const listType = listObj.listType || listObj.list_type;
+ let { position } = listObj;
+ if (listType === ListType.closed) {
+ position = Infinity;
+ } else if (listType === ListType.backlog) {
+ position = -1;
+ }
+
+ const list = new List({ ...listObj, position });
this.state.lists = sortBy([...this.state.lists, list], 'position');
return list;
},
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 0cc6f3df2d7..0a5538237f9 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -1,6 +1,5 @@
<script>
import { GlDeprecatedButton } from '@gitlab/ui';
-import envrionmentsAppMixin from 'ee_else_ce/environments/mixins/environments_app_mixin';
import Flash from '~/flash';
import { s__ } from '~/locale';
import emptyState from './empty_state.vue';
@@ -22,13 +21,18 @@ export default {
DeleteEnvironmentModal,
},
- mixins: [CIPaginationMixin, environmentsMixin, envrionmentsAppMixin],
+ mixins: [CIPaginationMixin, environmentsMixin],
props: {
endpoint: {
type: String,
required: true,
},
+ canaryDeploymentFeatureId: {
+ type: String,
+ required: false,
+ default: '',
+ },
canCreateEnvironment: {
type: Boolean,
required: true,
@@ -41,6 +45,11 @@ export default {
type: String,
required: true,
},
+ helpCanaryDeploymentsPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
helpPagePath: {
type: String,
required: true,
@@ -50,17 +59,37 @@ export default {
required: false,
default: '',
},
+ lockPromotionSvgPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ showCanaryDeploymentCallout: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ userCalloutsPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
created() {
eventHub.$on('toggleFolder', this.toggleFolder);
+ eventHub.$on('toggleDeployBoard', this.toggleDeployBoard);
},
beforeDestroy() {
eventHub.$off('toggleFolder');
+ eventHub.$off('toggleDeployBoard');
},
methods: {
+ toggleDeployBoard(model) {
+ this.store.toggleDeployBoard(model.id);
+ },
toggleFolder(folder) {
this.store.toggleFolder(folder);
diff --git a/app/assets/javascripts/environments/mixins/environments_app_mixin.js b/app/assets/javascripts/environments/mixins/environments_app_mixin.js
deleted file mode 100644
index fc805b9235a..00000000000
--- a/app/assets/javascripts/environments/mixins/environments_app_mixin.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default {
- props: {
- canaryDeploymentFeatureId: {
- type: String,
- required: false,
- default: '',
- },
- showCanaryDeploymentCallout: {
- type: Boolean,
- required: false,
- default: false,
- },
- userCalloutsPath: {
- type: String,
- required: false,
- default: '',
- },
- lockPromotionSvgPath: {
- type: String,
- required: false,
- default: '',
- },
- helpCanaryDeploymentsPath: {
- type: String,
- required: false,
- default: '',
- },
- },
- metods: {
- toggleDeployBoard() {},
- },
-};
diff --git a/app/assets/javascripts/environments/stores/environments_store.js b/app/assets/javascripts/environments/stores/environments_store.js
index 6b7c1ff627d..e07ec693948 100644
--- a/app/assets/javascripts/environments/stores/environments_store.js
+++ b/app/assets/javascripts/environments/stores/environments_store.js
@@ -133,6 +133,17 @@ export default class EnvironmentsStore {
}
/**
+ * Toggles deploy board visibility for the provided environment ID.
+ * Currently only works on EE.
+ *
+ * @param {Object} environment
+ * @return {Array}
+ */
+ toggleDeployBoard() {
+ return this.state.environments;
+ }
+
+ /**
* Toggles folder open property for the given folder.
*
* @param {Object} folder
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 6efddec1172..e4edcc2448c 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -12,6 +12,7 @@ import {
visibilityLevelDescriptions,
featureAccessLevelMembers,
featureAccessLevelEveryone,
+ featureAccessLevel,
} from '../constants';
import { toggleHiddenClassBySelector } from '../external';
@@ -127,7 +128,7 @@ export default {
wikiAccessLevel: 20,
snippetsAccessLevel: 20,
pagesAccessLevel: 20,
- metricsAccessLevel: visibilityOptions.PRIVATE,
+ metricsDashboardAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
containerRegistryEnabled: true,
lfsEnabled: true,
requestAccessEnabled: true,
@@ -174,6 +175,10 @@ export default {
return options;
},
+ metricsOptionsDropdownEnabled() {
+ return this.featureAccessLevelOptions.length < 2;
+ },
+
repositoryEnabled() {
return this.repositoryAccessLevel > 0;
},
@@ -211,6 +216,7 @@ export default {
this.buildsAccessLevel = Math.min(10, this.buildsAccessLevel);
this.wikiAccessLevel = Math.min(10, this.wikiAccessLevel);
this.snippetsAccessLevel = Math.min(10, this.snippetsAccessLevel);
+ this.metricsDashboardAccessLevel = Math.min(10, this.metricsDashboardAccessLevel);
if (this.pagesAccessLevel === 20) {
// When from Internal->Private narrow access for only members
this.pagesAccessLevel = 10;
@@ -225,6 +231,7 @@ export default {
if (this.wikiAccessLevel > 0) this.wikiAccessLevel = 20;
if (this.snippetsAccessLevel > 0) this.snippetsAccessLevel = 20;
if (this.pagesAccessLevel === 10) this.pagesAccessLevel = 20;
+ if (this.metricsDashboardAccessLevel === 10) this.metricsDashboardAccessLevel = 20;
this.highlightChanges();
}
},
@@ -485,17 +492,18 @@ export default {
<div class="project-feature-controls">
<div class="select-wrapper">
<select
- v-model="metricsAccessLevel"
+ v-model="metricsDashboardAccessLevel"
+ :disabled="metricsOptionsDropdownEnabled"
name="project[project_feature_attributes][metrics_dashboard_access_level]"
- class="form-control select-control"
+ class="form-control project-repo-select select-control"
>
<option
- :value="visibilityOptions.PRIVATE"
- :disabled="!visibilityAllowed(visibilityOptions.PRIVATE)"
+ :value="featureAccessLevelMembers[0]"
+ :disabled="!visibilityAllowed(visibilityOptions.INTERNAL)"
>{{ featureAccessLevelMembers[1] }}</option
>
<option
- :value="visibilityOptions.PUBLIC"
+ :value="featureAccessLevelEveryone[0]"
:disabled="!visibilityAllowed(visibilityOptions.PUBLIC)"
>{{ featureAccessLevelEveryone[1] }}</option
>
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 320bd4adaaa..7f50c50145b 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -434,6 +434,7 @@ img.emoji {
.append-bottom-20 { margin-bottom: 20px; }
.append-bottom-default { margin-bottom: $gl-padding; }
.prepend-bottom-32 { margin-bottom: 32px; }
+.ml-10 { margin-left: 4.5rem; }
.inline { display: inline-block; }
.center { text-align: center; }
.block { display: block; }