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-11-12 21:09:26 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-12 21:09:26 +0300
commitf4182abcb628e20978f011376811bbf8e644eff5 (patch)
treebb7886935855da9f69571b4970cfc5519dd40f2a /app/assets/javascripts
parent6cf30e964d54d536b0ff861916745f0a4bb31ebb (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/blob_edit/blob_bundle.js58
-rw-r--r--app/assets/javascripts/boards/components/board_assignee_dropdown.vue42
-rw-r--r--app/assets/javascripts/boards/queries/users_search.query.graphql11
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/show/index.js6
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js50
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_dag.js5
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_graph.js7
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue1
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/constants.js3
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js24
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/index.js10
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutation_types.js4
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutations.js30
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js16
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/store/utils.js11
15 files changed, 227 insertions, 51 deletions
diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js
index 2d426ee663a..f84e39baa53 100644
--- a/app/assets/javascripts/blob_edit/blob_bundle.js
+++ b/app/assets/javascripts/blob_edit/blob_bundle.js
@@ -8,11 +8,40 @@ import initPopover from '~/blob/suggest_gitlab_ci_yml';
import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils';
import Tracking from '~/tracking';
+const initPopovers = () => {
+ const suggestEl = document.querySelector('.js-suggest-gitlab-ci-yml');
+
+ if (suggestEl) {
+ const commitButton = document.querySelector('#commit-changes');
+
+ initPopover(suggestEl);
+
+ if (commitButton) {
+ const { dismissKey, humanAccess } = suggestEl.dataset;
+ const urlParams = new URLSearchParams(window.location.search);
+ const mergeRequestPath = urlParams.get('mr_path') || true;
+
+ const commitCookieName = `suggest_gitlab_ci_yml_commit_${dismissKey}`;
+ const commitTrackLabel = 'suggest_gitlab_ci_yml_commit_changes';
+ const commitTrackValue = '20';
+
+ commitButton.addEventListener('click', () => {
+ setCookie(commitCookieName, mergeRequestPath);
+
+ Tracking.event(undefined, 'click_button', {
+ label: commitTrackLabel,
+ property: humanAccess,
+ value: commitTrackValue,
+ });
+ });
+ }
+ }
+};
+
export default () => {
const editBlobForm = $('.js-edit-blob-form');
const uploadBlobForm = $('.js-upload-blob-form');
const deleteBlobForm = $('.js-delete-blob-form');
- const suggestEl = document.querySelector('.js-suggest-gitlab-ci-yml');
if (editBlobForm.length) {
const urlRoot = editBlobForm.data('relativeUrlRoot');
@@ -33,6 +62,7 @@ export default () => {
projectId,
isMarkdown,
});
+ initPopovers();
})
.catch(e => createFlash(e));
@@ -62,30 +92,4 @@ export default () => {
if (deleteBlobForm.length) {
new NewCommitForm(deleteBlobForm);
}
-
- if (suggestEl) {
- const commitButton = document.querySelector('#commit-changes');
-
- initPopover(suggestEl);
-
- if (commitButton) {
- const { dismissKey, humanAccess } = suggestEl.dataset;
- const urlParams = new URLSearchParams(window.location.search);
- const mergeRequestPath = urlParams.get('mr_path') || true;
-
- const commitCookieName = `suggest_gitlab_ci_yml_commit_${dismissKey}`;
- const commitTrackLabel = 'suggest_gitlab_ci_yml_commit_changes';
- const commitTrackValue = '20';
-
- commitButton.addEventListener('click', () => {
- setCookie(commitCookieName, mergeRequestPath);
-
- Tracking.event(undefined, 'click_button', {
- label: commitTrackLabel,
- property: humanAccess,
- value: commitTrackValue,
- });
- });
- }
- }
};
diff --git a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
index 2245c0d0f44..c81f171af2b 100644
--- a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
+++ b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
@@ -1,13 +1,22 @@
<script>
import { mapActions, mapGetters } from 'vuex';
-import { GlDropdownItem, GlDropdownDivider, GlAvatarLabeled, GlAvatarLink } from '@gitlab/ui';
+import {
+ GlDropdownItem,
+ GlDropdownDivider,
+ GlAvatarLabeled,
+ GlAvatarLink,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
import { __, n__ } from '~/locale';
import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees.vue';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import MultiSelectDropdown from '~/vue_shared/components/sidebar/multiselect_dropdown.vue';
import getIssueParticipants from '~/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql';
+import searchUsers from '~/boards/queries/users_search.query.graphql';
export default {
+ noSearchDelay: 0,
+ searchDelay: 250,
i18n: {
unassigned: __('Unassigned'),
assignee: __('Assignee'),
@@ -22,23 +31,42 @@ export default {
GlDropdownDivider,
GlAvatarLabeled,
GlAvatarLink,
+ GlSearchBoxByType,
},
data() {
return {
+ search: '',
participants: [],
selected: this.$store.getters.activeIssue.assignees,
};
},
apollo: {
participants: {
- query: getIssueParticipants,
+ query() {
+ return this.isSearchEmpty ? getIssueParticipants : searchUsers;
+ },
variables() {
+ if (this.isSearchEmpty) {
+ return {
+ id: `gid://gitlab/Issue/${this.activeIssue.iid}`,
+ };
+ }
+
return {
- id: `gid://gitlab/Issue/${this.activeIssue.iid}`,
+ search: this.search,
};
},
update(data) {
- return data.issue?.participants?.nodes || [];
+ if (this.isSearchEmpty) {
+ return data.issue?.participants?.nodes || [];
+ }
+
+ return data.users?.nodes || [];
+ },
+ debounce() {
+ const { noSearchDelay, searchDelay } = this.$options;
+
+ return this.isSearchEmpty ? noSearchDelay : searchDelay;
},
},
},
@@ -58,6 +86,9 @@ export default {
selectedUserNames() {
return this.selected.map(({ username }) => username);
},
+ isSearchEmpty() {
+ return this.search === '';
+ },
},
methods: {
...mapActions(['setAssignees']),
@@ -97,6 +128,9 @@ export default {
:text="$options.i18n.assignees"
:header-text="$options.i18n.assignTo"
>
+ <template #search>
+ <gl-search-box-by-type v-model.trim="search" />
+ </template>
<template #items>
<gl-dropdown-item
:is-checked="selectedIsEmpty"
diff --git a/app/assets/javascripts/boards/queries/users_search.query.graphql b/app/assets/javascripts/boards/queries/users_search.query.graphql
new file mode 100644
index 00000000000..ca016495d79
--- /dev/null
+++ b/app/assets/javascripts/boards/queries/users_search.query.graphql
@@ -0,0 +1,11 @@
+query usersSearch($search: String!) {
+ users(search: $search) {
+ nodes {
+ username
+ name
+ webUrl
+ avatarUrl
+ id
+ }
+ }
+}
diff --git a/app/assets/javascripts/pages/projects/pipelines/show/index.js b/app/assets/javascripts/pages/projects/pipelines/show/index.js
index 7a57e417b41..d3f46b7e025 100644
--- a/app/assets/javascripts/pages/projects/pipelines/show/index.js
+++ b/app/assets/javascripts/pages/projects/pipelines/show/index.js
@@ -1,7 +1,5 @@
import initPipelineDetails from '~/pipelines/pipeline_details_bundle';
import initPipelines from '../init_pipelines';
-document.addEventListener('DOMContentLoaded', () => {
- initPipelines();
- initPipelineDetails();
-});
+initPipelines();
+initPipelineDetails();
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index 67aec12655a..51d8bbeaef0 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -6,12 +6,10 @@ import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import pipelineGraph from './components/graph/graph_component.vue';
import createDagApp from './pipeline_details_dag';
import GraphBundleMixin from './mixins/graph_pipeline_bundle_mixin';
-import PipelinesMediator from './pipeline_details_mediator';
import legacyPipelineHeader from './components/legacy_header_component.vue';
import eventHub from './event_hub';
import TestReports from './components/test_reports/test_reports.vue';
import createTestReportsStore from './stores/test_reports';
-import { createPipelineHeaderApp } from './pipeline_details_header';
Vue.use(Translate);
@@ -22,7 +20,7 @@ const SELECTORS = {
PIPELINE_TESTS: '#js-pipeline-tests-detail',
};
-const createPipelinesDetailApp = mediator => {
+const createLegacyPipelinesDetailApp = mediator => {
if (!document.querySelector(SELECTORS.PIPELINE_GRAPH)) {
return;
}
@@ -127,18 +125,48 @@ const createTestDetails = () => {
});
};
-export default () => {
+export default async function() {
+ createTestDetails();
+ createDagApp();
+
const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS);
- const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
- mediator.fetchPipeline();
+ let mediator;
+
+ if (!gon.features.graphqlPipelineHeader || !gon.features.graphqlPipelineDetails) {
+ try {
+ const { default: PipelinesMediator } = await import(
+ /* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator'
+ );
+ mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
+ mediator.fetchPipeline();
+ } catch {
+ Flash(__('An error occurred while loading the pipeline.'));
+ }
+ }
- createPipelinesDetailApp(mediator);
+ if (gon.features.graphqlPipelineDetails) {
+ try {
+ const { createPipelinesDetailApp } = await import(
+ /* webpackChunkName: 'createPipelinesDetailApp' */ './pipeline_details_graph'
+ );
+ createPipelinesDetailApp();
+ } catch {
+ Flash(__('An error occurred while loading the pipeline.'));
+ }
+ } else {
+ createLegacyPipelinesDetailApp(mediator);
+ }
if (gon.features.graphqlPipelineHeader) {
- createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
+ try {
+ const { createPipelineHeaderApp } = await import(
+ /* webpackChunkName: 'createPipelineHeaderApp' */ './pipeline_details_header'
+ );
+ createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
+ } catch {
+ Flash(__('An error occurred while loading a section of this page.'));
+ }
} else {
createLegacyPipelineHeaderApp(mediator);
}
- createTestDetails();
- createDagApp();
-};
+}
diff --git a/app/assets/javascripts/pipelines/pipeline_details_dag.js b/app/assets/javascripts/pipelines/pipeline_details_dag.js
index dc03b457265..3e9bdae96dd 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_dag.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_dag.js
@@ -10,11 +10,12 @@ const apolloProvider = new VueApollo({
});
const createDagApp = () => {
- if (!window.gon?.features?.dagPipelineTab) {
+ const el = document.querySelector('#js-pipeline-dag-vue');
+
+ if (!window.gon?.features?.dagPipelineTab || !el) {
return;
}
- const el = document.querySelector('#js-pipeline-dag-vue');
const { pipelineProjectPath, pipelineIid, emptySvgPath, dagDocPath } = el?.dataset;
// eslint-disable-next-line no-new
diff --git a/app/assets/javascripts/pipelines/pipeline_details_graph.js b/app/assets/javascripts/pipelines/pipeline_details_graph.js
new file mode 100644
index 00000000000..880855cf21d
--- /dev/null
+++ b/app/assets/javascripts/pipelines/pipeline_details_graph.js
@@ -0,0 +1,7 @@
+const createPipelinesDetailApp = () => {
+ // Placeholder. See: https://gitlab.com/gitlab-org/gitlab/-/issues/223262
+ // eslint-disable-next-line no-useless-return
+ return;
+};
+
+export { createPipelinesDetailApp };
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue b/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue
index 68c97ed13d7..c5bbe1b33fb 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue
@@ -21,6 +21,7 @@ export default {
<template>
<gl-dropdown class="show" :text="text" :header-text="headerText">
+ <slot name="search"></slot>
<gl-dropdown-form>
<slot name="items"></slot>
</gl-dropdown-form>
diff --git a/app/assets/javascripts/vue_shared/security_reports/constants.js b/app/assets/javascripts/vue_shared/security_reports/constants.js
new file mode 100644
index 00000000000..2f87c4e7878
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/constants.js
@@ -0,0 +1,3 @@
+export const FEEDBACK_TYPE_DISMISSAL = 'dismissal';
+export const FEEDBACK_TYPE_ISSUE = 'issue';
+export const FEEDBACK_TYPE_MERGE_REQUEST = 'merge_request';
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js
new file mode 100644
index 00000000000..c9da824613d
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js
@@ -0,0 +1,24 @@
+import { fetchDiffData } from '../../utils';
+import * as types from './mutation_types';
+
+export const setDiffEndpoint = ({ commit }, path) => commit(types.SET_DIFF_ENDPOINT, path);
+
+export const requestDiff = ({ commit }) => commit(types.REQUEST_DIFF);
+
+export const receiveDiffSuccess = ({ commit }, response) =>
+ commit(types.RECEIVE_DIFF_SUCCESS, response);
+
+export const receiveDiffError = ({ commit }, response) =>
+ commit(types.RECEIVE_DIFF_ERROR, response);
+
+export const fetchDiff = ({ state, rootState, dispatch }) => {
+ dispatch('requestDiff');
+
+ return fetchDiffData(rootState, state.paths.diffEndpoint, 'secret_detection')
+ .then(data => {
+ dispatch('receiveDiffSuccess', data);
+ })
+ .catch(() => {
+ dispatch('receiveDiffError');
+ });
+};
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/index.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/index.js
new file mode 100644
index 00000000000..68c81bb4509
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/index.js
@@ -0,0 +1,10 @@
+import state from './state';
+import mutations from './mutations';
+import * as actions from './actions';
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+};
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutation_types.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutation_types.js
new file mode 100644
index 00000000000..aacec0fb679
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutation_types.js
@@ -0,0 +1,4 @@
+export const RECEIVE_DIFF_SUCCESS = 'RECEIVE_DIFF_SUCCESS';
+export const RECEIVE_DIFF_ERROR = 'RECEIVE_DIFF_ERROR';
+export const REQUEST_DIFF = 'REQUEST_DIFF';
+export const SET_DIFF_ENDPOINT = 'SET_DIFF_ENDPOINT';
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutations.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutations.js
new file mode 100644
index 00000000000..ee943b0621c
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutations.js
@@ -0,0 +1,30 @@
+import { parseDiff } from '~/vue_shared/security_reports/store/utils';
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_DIFF_ENDPOINT](state, path) {
+ state.paths.diffEndpoint = path;
+ },
+
+ [types.REQUEST_DIFF](state) {
+ state.isLoading = true;
+ },
+
+ [types.RECEIVE_DIFF_SUCCESS](state, { diff, enrichData }) {
+ const { added, fixed, existing } = parseDiff(diff, enrichData);
+ const baseReportOutofDate = diff.base_report_out_of_date || false;
+ const hasBaseReport = Boolean(diff.base_report_created_at);
+
+ state.isLoading = false;
+ state.newIssues = added;
+ state.resolvedIssues = fixed;
+ state.allIssues = existing;
+ state.baseReportOutofDate = baseReportOutofDate;
+ state.hasBaseReport = hasBaseReport;
+ },
+
+ [types.RECEIVE_DIFF_ERROR](state) {
+ state.isLoading = false;
+ state.hasError = true;
+ },
+};
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js
new file mode 100644
index 00000000000..e860e3af924
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js
@@ -0,0 +1,16 @@
+export default () => ({
+ paths: {
+ head: null,
+ base: null,
+ diffEndpoint: null,
+ },
+
+ isLoading: false,
+ hasError: false,
+
+ newIssues: [],
+ resolvedIssues: [],
+ allIssues: [],
+ baseReportOutofDate: false,
+ hasBaseReport: false,
+});
diff --git a/app/assets/javascripts/vue_shared/security_reports/store/utils.js b/app/assets/javascripts/vue_shared/security_reports/store/utils.js
index 9a3581e276e..6e50efae741 100644
--- a/app/assets/javascripts/vue_shared/security_reports/store/utils.js
+++ b/app/assets/javascripts/vue_shared/security_reports/store/utils.js
@@ -1,5 +1,10 @@
import pollUntilComplete from '~/lib/utils/poll_until_complete';
import axios from '~/lib/utils/axios_utils';
+import {
+ FEEDBACK_TYPE_DISMISSAL,
+ FEEDBACK_TYPE_ISSUE,
+ FEEDBACK_TYPE_MERGE_REQUEST,
+} from '../constants';
export const fetchDiffData = (state, endpoint, category) => {
const requests = [pollUntilComplete(endpoint)];
@@ -24,21 +29,21 @@ export const enrichVulnerabilityWithFeedback = (vulnerability, feedback = []) =>
feedback
.filter(fb => fb.project_fingerprint === vulnerability.project_fingerprint)
.reduce((vuln, fb) => {
- if (fb.feedback_type === 'dismissal') {
+ if (fb.feedback_type === FEEDBACK_TYPE_DISMISSAL) {
return {
...vuln,
isDismissed: true,
dismissalFeedback: fb,
};
}
- if (fb.feedback_type === 'issue' && fb.issue_iid) {
+ if (fb.feedback_type === FEEDBACK_TYPE_ISSUE && fb.issue_iid) {
return {
...vuln,
hasIssue: true,
issue_feedback: fb,
};
}
- if (fb.feedback_type === 'merge_request' && fb.merge_request_iid) {
+ if (fb.feedback_type === FEEDBACK_TYPE_MERGE_REQUEST && fb.merge_request_iid) {
return {
...vuln,
hasMergeRequest: true,