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:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/ci_variable_list/ajax_variable_list.js2
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js12
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue37
-rw-r--r--app/assets/javascripts/clusters/services/clusters_service.js1
-rw-r--r--app/assets/javascripts/clusters/stores/clusters_store.js7
-rw-r--r--app/assets/javascripts/diffs/components/app.vue55
-rw-r--r--app/assets/javascripts/diffs/components/commit_widget.vue2
-rw-r--r--app/assets/javascripts/diffs/components/compare_versions.vue23
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue4
-rw-r--r--app/assets/javascripts/dismissable_callout.js27
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js18
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js4
-rw-r--r--app/assets/javascripts/ide/stores/actions/merge_request.js6
-rw-r--r--app/assets/javascripts/ide/stores/actions/project.js2
-rw-r--r--app/assets/javascripts/ide/stores/actions/tree.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/pipelines/actions.js6
-rw-r--r--app/assets/javascripts/jobs/components/sidebar.vue2
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue13
-rw-r--r--app/assets/javascripts/notes/components/toggle_replies_widget.vue2
-rw-r--r--app/assets/javascripts/pages/groups/clusters/index/index.js6
-rw-r--r--app/assets/javascripts/pages/groups/index.js10
-rw-r--r--app/assets/javascripts/pages/projects/clusters/index/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/index.js6
-rw-r--r--app/assets/javascripts/pages/root/index.js5
-rw-r--r--app/assets/javascripts/persistent_user_callout.js34
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue2
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue2
27 files changed, 187 insertions, 109 deletions
diff --git a/app/assets/javascripts/ci_variable_list/ajax_variable_list.js b/app/assets/javascripts/ci_variable_list/ajax_variable_list.js
index c7a917457f3..dffabbfe1b8 100644
--- a/app/assets/javascripts/ci_variable_list/ajax_variable_list.js
+++ b/app/assets/javascripts/ci_variable_list/ajax_variable_list.js
@@ -84,7 +84,7 @@ export default class AjaxVariableList {
.catch(() => {
loadingIcon.classList.toggle('hide', true);
this.variableList.toggleEnableRow(true);
- Flash(s__('CiVariable|Error occured while saving variables'));
+ Flash(s__('CiVariable|Error occurred while saving variables'));
});
}
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index 71fc2ac7d80..aff32d95db1 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -1,6 +1,6 @@
import Visibility from 'visibilityjs';
import Vue from 'vue';
-import initDismissableCallout from '~/dismissable_callout';
+import PersistentUserCallout from '../persistent_user_callout';
import { s__, sprintf } from '../locale';
import Flash from '../flash';
import Poll from '../lib/utils/poll';
@@ -26,6 +26,7 @@ export default class Clusters {
statusPath,
installHelmPath,
installIngressPath,
+ installCertManagerPath,
installRunnerPath,
installJupyterPath,
installKnativePath,
@@ -48,6 +49,7 @@ export default class Clusters {
endpoint: statusPath,
installHelmEndpoint: installHelmPath,
installIngressEndpoint: installIngressPath,
+ installCertManagerEndpoint: installCertManagerPath,
installRunnerEndpoint: installRunnerPath,
installPrometheusEndpoint: installPrometheusPath,
installJupyterEndpoint: installJupyterPath,
@@ -65,7 +67,7 @@ export default class Clusters {
this.showTokenButton = document.querySelector('.js-show-cluster-token');
this.tokenField = document.querySelector('.js-cluster-token');
- initDismissableCallout('.js-cluster-security-warning');
+ Clusters.initDismissableCallout();
initSettingsPanels();
setupToggleButtons(document.querySelector('.js-cluster-enable-toggle-area'));
this.initApplications(clusterType);
@@ -106,6 +108,12 @@ export default class Clusters {
});
}
+ static initDismissableCallout() {
+ const callout = document.querySelector('.js-cluster-security-warning');
+
+ if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
+ }
+
addListeners() {
if (this.showTokenButton) this.showTokenButton.addEventListener('click', this.showToken);
eventHub.$on('installApplication', this.installApplication);
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index 0d2e7c3e356..fcdbffbc8b8 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -7,6 +7,7 @@ import helmLogo from 'images/cluster_app_logos/helm.png';
import jeagerLogo from 'images/cluster_app_logos/jeager.png';
import jupyterhubLogo from 'images/cluster_app_logos/jupyterhub.png';
import kubernetesLogo from 'images/cluster_app_logos/kubernetes.png';
+import certManagerLogo from 'images/cluster_app_logos/cert_manager.png';
import knativeLogo from 'images/cluster_app_logos/knative.png';
import meltanoLogo from 'images/cluster_app_logos/meltano.png';
import prometheusLogo from 'images/cluster_app_logos/prometheus.png';
@@ -59,6 +60,7 @@ export default {
jeagerLogo,
jupyterhubLogo,
kubernetesLogo,
+ certManagerLogo,
knativeLogo,
meltanoLogo,
prometheusLogo,
@@ -124,6 +126,23 @@ export default {
</p>
`;
},
+ certManagerDescription() {
+ return sprintf(
+ _.escape(
+ s__(
+ `ClusterIntegration|cert-manager is a native Kubernetes certificate management controller that helps with issuing certificates.
+ Installing cert-manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates
+ are valid and up to date.`,
+ ),
+ ),
+ {
+ letsEncrypt: `<a href="https://letsencrypt.org/"
+ target="_blank" rel="noopener noreferrer">
+ ${_.escape(s__("ClusterIntegration|Let's Encrypt"))}</a>`,
+ },
+ false,
+ );
+ },
prometheusDescription() {
return sprintf(
_.escape(
@@ -266,6 +285,24 @@ export default {
</div>
</application-row>
<application-row
+ id="cert_manager"
+ :logo-url="certManagerLogo"
+ :title="applications.cert_manager.title"
+ :status="applications.cert_manager.status"
+ :status-reason="applications.cert_manager.statusReason"
+ :request-status="applications.cert_manager.requestStatus"
+ :request-reason="applications.cert_manager.requestReason"
+ :disabled="!helmInstalled"
+ class="hide-bottom-border rounded-bottom"
+ title-link="https://cert-manager.readthedocs.io/en/latest/#"
+ >
+ <div
+ slot="description"
+ v-html="certManagerDescription"
+ >
+ </div>
+ </application-row>
+ <application-row
v-if="isProjectCluster"
id="prometheus"
:logo-url="prometheusLogo"
diff --git a/app/assets/javascripts/clusters/services/clusters_service.js b/app/assets/javascripts/clusters/services/clusters_service.js
index da562b09ee5..89dda4b7902 100644
--- a/app/assets/javascripts/clusters/services/clusters_service.js
+++ b/app/assets/javascripts/clusters/services/clusters_service.js
@@ -6,6 +6,7 @@ export default class ClusterService {
this.appInstallEndpointMap = {
helm: this.options.installHelmEndpoint,
ingress: this.options.installIngressEndpoint,
+ cert_manager: this.options.installCertManagerEndpoint,
runner: this.options.installRunnerEndpoint,
prometheus: this.options.installPrometheusEndpoint,
jupyter: this.options.installJupyterEndpoint,
diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js
index e45da967392..3678be59d24 100644
--- a/app/assets/javascripts/clusters/stores/clusters_store.js
+++ b/app/assets/javascripts/clusters/stores/clusters_store.js
@@ -24,6 +24,13 @@ export default class ClusterStore {
requestReason: null,
externalIp: null,
},
+ cert_manager: {
+ title: s__('ClusterIntegration|Cert-Manager'),
+ status: null,
+ statusReason: null,
+ requestStatus: null,
+ requestReason: null,
+ },
runner: {
title: s__('ClusterIntegration|GitLab Runner'),
status: null,
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 0b7838292b2..22da38ce7a5 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -55,8 +55,6 @@ export default {
diffViewType: state => state.diffs.diffViewType,
mergeRequestDiffs: state => state.diffs.mergeRequestDiffs,
mergeRequestDiff: state => state.diffs.mergeRequestDiff,
- latestVersionPath: state => state.diffs.latestVersionPath,
- startVersion: state => state.diffs.startVersion,
commit: state => state.diffs.commit,
targetBranchName: state => state.diffs.targetBranchName,
renderOverflowWarning: state => state.diffs.renderOverflowWarning,
@@ -75,24 +73,6 @@ export default {
path: '',
};
},
- notAllCommentsDisplayed() {
- if (this.commit) {
- return __('Only comments from the following commit are shown below');
- } else if (this.startVersion) {
- return __(
- "Not all comments are displayed because you're comparing two versions of the diff.",
- );
- }
- return __(
- "Not all comments are displayed because you're viewing an old version of the diff.",
- );
- },
- showLatestVersion() {
- if (this.commit) {
- return __('Show latest version of the diff');
- }
- return __('Show latest version');
- },
canCurrentUserFork() {
return this.currentUser.can_fork === true && this.currentUser.can_create_merge_request;
},
@@ -184,10 +164,8 @@ export default {
<div v-if="isLoading" class="loading"><gl-loading-icon /></div>
<div v-else id="diffs" :class="{ active: shouldShow }" class="diffs tab-pane">
<compare-versions
- v-if="showCompareVersions"
:merge-request-diffs="mergeRequestDiffs"
:merge-request-diff="mergeRequestDiff"
- :start-version="startVersion"
:target-branch="targetBranch"
/>
@@ -200,33 +178,22 @@ export default {
/>
<div
- v-if="commit || startVersion || (mergeRequestDiff && !mergeRequestDiff.latest)"
- class="mr-version-controls"
- >
- <div class="content-block comments-disabled-notif clearfix">
- <i class="fa fa-info-circle"></i> {{ notAllCommentsDisplayed }}
- <div class="pull-right">
- <a :href="latestVersionPath" class="btn btn-sm"> {{ showLatestVersion }} </a>
- </div>
- </div>
- </div>
-
- <commit-widget v-if="commit" :commit="commit" />
-
- <div
:data-can-create-note="getNoteableData.current_user.can_create_note"
class="files d-flex prepend-top-default"
>
<div v-show="showTreeList" class="diff-tree-list"><tree-list /></div>
- <div v-if="diffFiles.length > 0" class="diff-files-holder">
- <diff-file
- v-for="file in diffFiles"
- :key="file.newPath"
- :file="file"
- :can-current-user-fork="canCurrentUserFork"
- />
+ <div class="diff-files-holder">
+ <commit-widget v-if="commit" :commit="commit" />
+ <template v-if="diffFiles.length > 0">
+ <diff-file
+ v-for="file in diffFiles"
+ :key="file.newPath"
+ :file="file"
+ :can-current-user-fork="canCurrentUserFork"
+ />
+ </template>
+ <no-changes v-else />
</div>
- <no-changes v-else />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/diffs/components/commit_widget.vue b/app/assets/javascripts/diffs/components/commit_widget.vue
index 3fb11813d68..d45f91c7023 100644
--- a/app/assets/javascripts/diffs/components/commit_widget.vue
+++ b/app/assets/javascripts/diffs/components/commit_widget.vue
@@ -28,7 +28,7 @@ export default {
</script>
<template>
- <div class="info-well prepend-top-default">
+ <div class="info-well w-100">
<div class="well-segment">
<ul class="blob-commit-info">
<commit-item :commit="commit" />
diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue
index 3ccd111f1cb..f75345d31f8 100644
--- a/app/assets/javascripts/diffs/components/compare_versions.vue
+++ b/app/assets/javascripts/diffs/components/compare_versions.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import { GlTooltipDirective } from '@gitlab/ui';
+import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import { getParameterValues, mergeUrlParams } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
@@ -10,6 +10,8 @@ export default {
components: {
CompareVersionsDropdown,
Icon,
+ GlLink,
+ GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -21,12 +23,8 @@ export default {
},
mergeRequestDiff: {
type: Object,
- required: true,
- },
- startVersion: {
- type: Object,
required: false,
- default: null,
+ default: () => ({}),
},
targetBranch: {
type: Object,
@@ -35,7 +33,7 @@ export default {
},
},
computed: {
- ...mapState('diffs', ['commit', 'showTreeList']),
+ ...mapState('diffs', ['commit', 'showTreeList', 'startVersion', 'latestVersionPath']),
...mapGetters('diffs', ['isInlineView', 'isParallelView', 'hasCollapsedFile']),
comparableDiffs() {
return this.mergeRequestDiffs.slice(1);
@@ -102,7 +100,18 @@ export default {
class="mr-version-compare-dropdown"
/>
</div>
+ <div v-else-if="commit">
+ {{ __('Viewing commit') }}
+ <gl-link :href="commit.commit_url" class="monospace">{{ commit.short_id }}</gl-link>
+ </div>
<div class="inline-parallel-buttons d-none d-md-flex ml-auto">
+ <gl-button
+ v-if="commit || startVersion"
+ :href="latestVersionPath"
+ class="append-right-8 js-latest-version"
+ >
+ {{ __('Show latest version') }}
+ </gl-button>
<a v-show="hasCollapsedFile" class="btn btn-default append-right-8" @click="expandAllFiles">
{{ __('Expand all') }}
</a>
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 60b33e771b4..f75a01b023b 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -1,6 +1,7 @@
<script>
import _ from 'underscore';
import { mapActions, mapGetters } from 'vuex';
+import { polyfillSticky } from '~/lib/utils/sticky';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import Icon from '~/vue_shared/components/icon.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -116,6 +117,9 @@ export default {
return `\`${this.diffFile.file_path}\``;
},
},
+ mounted() {
+ polyfillSticky(this.$refs.header);
+ },
methods: {
...mapActions('diffs', ['toggleFileDiscussions']),
handleToggleFile(e, checkTarget) {
diff --git a/app/assets/javascripts/dismissable_callout.js b/app/assets/javascripts/dismissable_callout.js
deleted file mode 100644
index 5185b019376..00000000000
--- a/app/assets/javascripts/dismissable_callout.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import $ from 'jquery';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
-import Flash from '~/flash';
-
-export default function initDismissableCallout(alertSelector) {
- const alertEl = document.querySelector(alertSelector);
- if (!alertEl) {
- return;
- }
-
- const closeButtonEl = alertEl.getElementsByClassName('close')[0];
- const { dismissEndpoint, featureId } = closeButtonEl.dataset;
-
- closeButtonEl.addEventListener('click', () => {
- axios
- .post(dismissEndpoint, {
- feature_name: featureId,
- })
- .then(() => {
- $(alertEl).alert('close');
- })
- .catch(() => {
- Flash(__('An error occurred while dismissing the alert. Refresh the page and try again.'));
- });
- });
-}
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 6f8b73564d0..c14eb936930 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -62,9 +62,11 @@ class GfmAutoComplete {
skipMarkdownCharacterTest: true,
data: GfmAutoComplete.defaultLoadingData,
displayTpl(value) {
+ const cssClasses = [];
+
if (GfmAutoComplete.isLoading(value)) return GfmAutoComplete.Loading.template;
// eslint-disable-next-line no-template-curly-in-string
- let tpl = '<li><span class="name">/${name}</span>';
+ let tpl = '<li class="<%- className %>"><span class="name">/${name}</span>';
if (value.aliases.length > 0) {
tpl += ' <small class="aliases">(or /<%- aliases.join(", /") %>)</small>';
}
@@ -72,10 +74,19 @@ class GfmAutoComplete {
tpl += ' <small class="params"><%- params.join(" ") %></small>';
}
if (value.description !== '') {
- tpl += '<small class="description"><i><%- description %></i></small>';
+ tpl += '<small class="description"><i><%- description %> <%- warningText %></i></small>';
}
tpl += '</li>';
- return _.template(tpl)(value);
+
+ if (value.warning) {
+ cssClasses.push('has-warning');
+ }
+
+ return _.template(tpl)({
+ ...value,
+ className: cssClasses.join(' '),
+ warningText: value.warning ? `(${value.warning})` : '',
+ });
},
insertTpl(value) {
// eslint-disable-next-line no-template-curly-in-string
@@ -104,6 +115,7 @@ class GfmAutoComplete {
aliases: c.aliases,
params: c.params,
description: c.description,
+ warning: c.warning,
search,
};
});
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index a297740bd5f..e74b880e02c 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -82,7 +82,7 @@ export const getFileData = (
.catch(() => {
commit(types.TOGGLE_LOADING, { entry: file });
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading the file.'),
+ text: __('An error occurred whilst loading the file.'),
action: payload =>
dispatch('getFileData', payload).then(() => dispatch('setErrorMessage', null)),
actionText: __('Please try again'),
@@ -124,7 +124,7 @@ export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) =
})
.catch(() => {
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading the file content.'),
+ text: __('An error occurred whilst loading the file content.'),
action: payload =>
dispatch('getRawFileData', payload).then(() => dispatch('setErrorMessage', null)),
actionText: __('Please try again'),
diff --git a/app/assets/javascripts/ide/stores/actions/merge_request.js b/app/assets/javascripts/ide/stores/actions/merge_request.js
index 8404c6d4f72..18c24369996 100644
--- a/app/assets/javascripts/ide/stores/actions/merge_request.js
+++ b/app/assets/javascripts/ide/stores/actions/merge_request.js
@@ -25,7 +25,7 @@ export const getMergeRequestData = (
})
.catch(() => {
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading the merge request.'),
+ text: __('An error occurred whilst loading the merge request.'),
action: payload =>
dispatch('getMergeRequestData', payload).then(() =>
dispatch('setErrorMessage', null),
@@ -58,7 +58,7 @@ export const getMergeRequestChanges = (
})
.catch(() => {
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading the merge request changes.'),
+ text: __('An error occurred whilst loading the merge request changes.'),
action: payload =>
dispatch('getMergeRequestChanges', payload).then(() =>
dispatch('setErrorMessage', null),
@@ -92,7 +92,7 @@ export const getMergeRequestVersions = (
})
.catch(() => {
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading the merge request version data.'),
+ text: __('An error occurred whilst loading the merge request version data.'),
action: payload =>
dispatch('getMergeRequestVersions', payload).then(() =>
dispatch('setErrorMessage', null),
diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js
index 2cb08ab2945..b65f631c99c 100644
--- a/app/assets/javascripts/ide/stores/actions/project.js
+++ b/app/assets/javascripts/ide/stores/actions/project.js
@@ -103,7 +103,7 @@ export const createNewBranchFromDefault = ({ state, dispatch, getters }, branch)
})
.catch(() => {
dispatch('setErrorMessage', {
- text: __('An error occured creating the new branch.'),
+ text: __('An error occurred creating the new branch.'),
action: payload => dispatch('createNewBranchFromDefault', payload),
actionText: __('Please try again'),
actionPayload: branch,
diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js
index 9288bbe32f5..de5f6050074 100644
--- a/app/assets/javascripts/ide/stores/actions/tree.js
+++ b/app/assets/javascripts/ide/stores/actions/tree.js
@@ -76,7 +76,7 @@ export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } =
dispatch('showBranchNotFoundError', branchId);
} else {
dispatch('setErrorMessage', {
- text: __('An error occured whilst loading all the files.'),
+ text: __('An error occurred whilst loading all the files.'),
action: payload =>
dispatch('getFiles', payload).then(() => dispatch('setErrorMessage', null)),
actionText: __('Please try again'),
diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
index ea2525a2f0e..51cf4dede42 100644
--- a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
@@ -28,7 +28,7 @@ export const receiveLatestPipelineError = ({ commit, dispatch }, err) => {
dispatch(
'setErrorMessage',
{
- text: __('An error occured whilst fetching the latest pipeline.'),
+ text: __('An error occurred whilst fetching the latest pipeline.'),
action: () =>
dispatch('forcePipelineRequest').then(() =>
dispatch('setErrorMessage', null, { root: true }),
@@ -84,7 +84,7 @@ export const receiveJobsError = ({ commit, dispatch }, stage) => {
dispatch(
'setErrorMessage',
{
- text: __('An error occured whilst loading the pipelines jobs.'),
+ text: __('An error occurred whilst loading the pipelines jobs.'),
action: payload =>
dispatch('fetchJobs', payload).then(() =>
dispatch('setErrorMessage', null, { root: true }),
@@ -123,7 +123,7 @@ export const receiveJobTraceError = ({ commit, dispatch }) => {
dispatch(
'setErrorMessage',
{
- text: __('An error occured whilst fetching the job trace.'),
+ text: __('An error occurred whilst fetching the job trace.'),
action: () =>
dispatch('fetchJobTrace').then(() => dispatch('setErrorMessage', null, { root: true })),
actionText: __('Please try again'),
diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue
index 0f590e077bf..934ecd0e3ec 100644
--- a/app/assets/javascripts/jobs/components/sidebar.vue
+++ b/app/assets/javascripts/jobs/components/sidebar.vue
@@ -199,7 +199,7 @@ export default {
/>
<p v-if="job.tags.length" class="build-detail-row js-job-tags">
<span class="build-light-text"> {{ __('Tags:') }} </span>
- <span v-for="(tag, i) in job.tags" :key="i" class="label label-primary">
+ <span v-for="(tag, i) in job.tags" :key="i" class="badge badge-primary">
{{ tag }}
</span>
</p>
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index f6842fa240e..29740ddf6ae 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -68,7 +68,7 @@ export default {
isReplying: false,
isResolving: false,
resolveAsThread: true,
- isRepliesCollapsed: (!this.discussion.diff_discussion && this.discussion.resolved) || false,
+ isRepliesToggledByUser: false,
};
},
computed: {
@@ -189,6 +189,15 @@ export default {
return isExpanded || this.alwaysExpanded || isResolvedNonDiffDiscussion;
},
+ isRepliesCollapsed() {
+ const { discussion, isRepliesToggledByUser } = this;
+ const { resolved, notes } = discussion;
+ const hasReplies = notes.length > 1;
+
+ return (
+ (!discussion.diff_discussion && resolved && hasReplies && !isRepliesToggledByUser) || false
+ );
+ },
},
watch: {
isReplying() {
@@ -233,7 +242,7 @@ export default {
this.toggleDiscussion({ discussionId: this.discussion.id });
},
toggleReplies() {
- this.isRepliesCollapsed = !this.isRepliesCollapsed;
+ this.isRepliesToggledByUser = !this.isRepliesToggledByUser;
},
showReplyForm() {
this.isReplying = true;
diff --git a/app/assets/javascripts/notes/components/toggle_replies_widget.vue b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
index e9d05c5cdcd..72a8ff28466 100644
--- a/app/assets/javascripts/notes/components/toggle_replies_widget.vue
+++ b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
@@ -42,7 +42,7 @@ export default {
</script>
<template>
- <li :class="className" class="replies-toggle">
+ <li :class="className" class="replies-toggle js-toggle-replies">
<template v-if="collapsed">
<icon name="chevron-right" @click.native="toggle" />
<div>
diff --git a/app/assets/javascripts/pages/groups/clusters/index/index.js b/app/assets/javascripts/pages/groups/clusters/index/index.js
index 845a5f7042c..21efc4f6d00 100644
--- a/app/assets/javascripts/pages/groups/clusters/index/index.js
+++ b/app/assets/javascripts/pages/groups/clusters/index/index.js
@@ -1,5 +1,7 @@
-import initDismissableCallout from '~/dismissable_callout';
+import PersistentUserCallout from '~/persistent_user_callout';
document.addEventListener('DOMContentLoaded', () => {
- initDismissableCallout('.gcp-signup-offer');
+ const callout = document.querySelector('.gcp-signup-offer');
+
+ if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
});
diff --git a/app/assets/javascripts/pages/groups/index.js b/app/assets/javascripts/pages/groups/index.js
index bf80d8b8193..00e2d7fc998 100644
--- a/app/assets/javascripts/pages/groups/index.js
+++ b/app/assets/javascripts/pages/groups/index.js
@@ -1,6 +1,12 @@
-import initDismissableCallout from '~/dismissable_callout';
+import PersistentUserCallout from '~/persistent_user_callout';
import initGkeDropdowns from '~/projects/gke_cluster_dropdowns';
+function initCallout() {
+ const callout = document.querySelector('.gcp-signup-offer');
+
+ if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
+}
+
document.addEventListener('DOMContentLoaded', () => {
const { page } = document.body.dataset;
const newClusterViews = [
@@ -10,7 +16,7 @@ document.addEventListener('DOMContentLoaded', () => {
];
if (newClusterViews.indexOf(page) > -1) {
- initDismissableCallout('.gcp-signup-offer');
+ initCallout();
initGkeDropdowns();
}
});
diff --git a/app/assets/javascripts/pages/projects/clusters/index/index.js b/app/assets/javascripts/pages/projects/clusters/index/index.js
index 845a5f7042c..21efc4f6d00 100644
--- a/app/assets/javascripts/pages/projects/clusters/index/index.js
+++ b/app/assets/javascripts/pages/projects/clusters/index/index.js
@@ -1,5 +1,7 @@
-import initDismissableCallout from '~/dismissable_callout';
+import PersistentUserCallout from '~/persistent_user_callout';
document.addEventListener('DOMContentLoaded', () => {
- initDismissableCallout('.gcp-signup-offer');
+ const callout = document.querySelector('.gcp-signup-offer');
+
+ if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
});
diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js
index 5659e13981a..b0345b4e50d 100644
--- a/app/assets/javascripts/pages/projects/index.js
+++ b/app/assets/javascripts/pages/projects/index.js
@@ -1,5 +1,5 @@
-import initDismissableCallout from '~/dismissable_callout';
import initGkeDropdowns from '~/projects/gke_cluster_dropdowns';
+import PersistentUserCallout from '../../persistent_user_callout';
import Project from './project';
import ShortcutsNavigation from '../../behaviors/shortcuts/shortcuts_navigation';
@@ -12,7 +12,9 @@ document.addEventListener('DOMContentLoaded', () => {
];
if (newClusterViews.indexOf(page) > -1) {
- initDismissableCallout('.gcp-signup-offer');
+ const callout = document.querySelector('.gcp-signup-offer');
+ if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
+
initGkeDropdowns();
}
diff --git a/app/assets/javascripts/pages/root/index.js b/app/assets/javascripts/pages/root/index.js
new file mode 100644
index 00000000000..09f8185d3b5
--- /dev/null
+++ b/app/assets/javascripts/pages/root/index.js
@@ -0,0 +1,5 @@
+// if the "projects dashboard" is a user's default dashboard, when they visit the
+// instance root index, the dashboard will be served by the root controller instead
+// of a dashboard controller. The root index redirects for all other default dashboards.
+
+import '../dashboard/projects/index';
diff --git a/app/assets/javascripts/persistent_user_callout.js b/app/assets/javascripts/persistent_user_callout.js
new file mode 100644
index 00000000000..1e34e74a152
--- /dev/null
+++ b/app/assets/javascripts/persistent_user_callout.js
@@ -0,0 +1,34 @@
+import axios from './lib/utils/axios_utils';
+import { __ } from './locale';
+import Flash from './flash';
+
+export default class PersistentUserCallout {
+ constructor(container) {
+ const { dismissEndpoint, featureId } = container.dataset;
+ this.container = container;
+ this.dismissEndpoint = dismissEndpoint;
+ this.featureId = featureId;
+
+ this.init();
+ }
+
+ init() {
+ const closeButton = this.container.querySelector('.js-close');
+ closeButton.addEventListener('click', event => this.dismiss(event));
+ }
+
+ dismiss(event) {
+ event.preventDefault();
+
+ axios
+ .post(this.dismissEndpoint, {
+ feature_name: this.featureId,
+ })
+ .then(() => {
+ this.container.remove();
+ })
+ .catch(() => {
+ Flash(__('An error occurred while dismissing the alert. Refresh the page and try again.'));
+ });
+ }
+}
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue
index 78f085e5312..21095fcba16 100644
--- a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue
@@ -47,7 +47,7 @@ export default {
errorMessage() {
return sprintf(
s__(
- 'ClusterIntegration|An error occured while trying to fetch zone machine types: %{error}',
+ 'ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}',
),
{ error: this.gapiError },
);
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue
index 8e51dd352c7..056584c8865 100644
--- a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue
@@ -93,7 +93,7 @@ export default {
}
return sprintf(
- s__('ClusterIntegration|An error occured while trying to fetch your projects: %{error}'),
+ s__('ClusterIntegration|An error occurred while trying to fetch your projects: %{error}'),
{ error: this.gapiError },
);
},