summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-19 12:09:13 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-19 12:09:13 +0000
commitcd3e2c7b9355f8990ab294b34b5e4add4f3985fa (patch)
tree77264b3e569ec95da8476f604d3d5cf4b03e85dc /app
parentc1fc5da123a1fe670e32740669a9d5e59eff38f5 (diff)
downloadgitlab-ce-cd3e2c7b9355f8990ab294b34b5e4add4f3985fa.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/blob/template_selector.js4
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js7
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue41
-rw-r--r--app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue116
-rw-r--r--app/assets/javascripts/clusters/stores/clusters_store.js9
-rw-r--r--app/assets/javascripts/repository/components/preview/index.vue13
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss6
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
9 files changed, 162 insertions, 38 deletions
diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js
index b0de4dc8628..2427e25a17d 100644
--- a/app/assets/javascripts/blob/template_selector.js
+++ b/app/assets/javascripts/blob/template_selector.js
@@ -92,10 +92,10 @@ export default class TemplateSelector {
}
startLoadingSpinner() {
- this.$dropdownIcon.addClass('fa-spinner fa-spin').removeClass('fa-chevron-down');
+ this.$dropdownIcon.addClass('spinner').removeClass('fa-chevron-down');
}
stopLoadingSpinner() {
- this.$dropdownIcon.addClass('fa-chevron-down').removeClass('fa-spinner fa-spin');
+ this.$dropdownIcon.addClass('fa-chevron-down').removeClass('spinner');
}
}
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index b764348eb3c..d35dca7b939 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -255,6 +255,7 @@ export default class Clusters {
eventHub.$on('setKnativeHostname', data => this.setKnativeHostname(data));
eventHub.$on('uninstallApplication', data => this.uninstallApplication(data));
eventHub.$on('setCrossplaneProviderStack', data => this.setCrossplaneProviderStack(data));
+ eventHub.$on('setIngressModSecurityEnabled', data => this.setIngressModSecurityEnabled(data));
// Add event listener to all the banner close buttons
this.addBannerCloseHandler(this.unreachableContainer, 'unreachable');
this.addBannerCloseHandler(this.authenticationFailureContainer, 'authentication_failure');
@@ -268,6 +269,7 @@ export default class Clusters {
eventHub.$off('setKnativeHostname');
eventHub.$off('setCrossplaneProviderStack');
eventHub.$off('uninstallApplication');
+ eventHub.$off('setIngressModSecurityEnabled');
}
initPolling(method, successCallback, errorCallback) {
@@ -513,6 +515,11 @@ export default class Clusters {
this.store.updateAppProperty(appId, 'validationError', null);
}
+ setIngressModSecurityEnabled({ id, modSecurityEnabled }) {
+ this.store.updateAppProperty(id, 'isEditingModSecurityEnabled', true);
+ this.store.updateAppProperty(id, 'modsecurity_enabled', modSecurityEnabled);
+ }
+
destroy() {
this.destroyed = true;
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index fe2ad562ad5..9429e10e6ed 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -21,6 +21,7 @@ import KnativeDomainEditor from './knative_domain_editor.vue';
import { CLUSTER_TYPE, PROVIDER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';
import eventHub from '~/clusters/event_hub';
import CrossplaneProviderStack from './crossplane_provider_stack.vue';
+import IngressModsecuritySettings from './ingress_modsecurity_settings.vue';
export default {
components: {
@@ -29,6 +30,7 @@ export default {
GlLoadingIcon,
KnativeDomainEditor,
CrossplaneProviderStack,
+ IngressModsecuritySettings,
},
props: {
type: {
@@ -129,18 +131,6 @@ export default {
crossplaneInstalled() {
return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED;
},
- ingressModSecurityDescription() {
- const escapedUrl = _.escape(this.ingressModSecurityHelpPath);
-
- return sprintf(
- s__('ClusterIntegration|Learn more about %{startLink}ModSecurity%{endLink}'),
- {
- startLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
- endLink: '</a>',
- },
- false,
- );
- },
ingressDescription() {
return sprintf(
_.escape(
@@ -241,6 +231,9 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
}
return null;
},
+ ingress() {
+ return this.applications.ingress;
+ },
},
created() {
this.helmInstallIllustration = helmInstallIllustration;
@@ -329,6 +322,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:uninstall-successful="applications.ingress.uninstallSuccessful"
:uninstall-failed="applications.ingress.uninstallFailed"
:disabled="!helmInstalled"
+ :updateable="false"
title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
>
<div slot="description">
@@ -340,25 +334,10 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
}}
</p>
- <template>
- <div class="form-group">
- <div class="form-check form-check-inline">
- <input
- v-model="applications.ingress.modsecurity_enabled"
- :disabled="ingressInstalled"
- type="checkbox"
- autocomplete="off"
- class="form-check-input"
- />
- <label class="form-check-label label-bold" for="ingress-enable-modsecurity">
- {{ s__('ClusterIntegration|Enable Web Application Firewall') }}
- </label>
- </div>
- <p class="form-text text-muted">
- <strong v-html="ingressModSecurityDescription"></strong>
- </p>
- </div>
- </template>
+ <ingress-modsecurity-settings
+ :ingress="ingress"
+ :ingress-mod-security-help-path="ingressModSecurityHelpPath"
+ />
<template v-if="ingressInstalled">
<div class="form-group">
diff --git a/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
new file mode 100644
index 00000000000..c30015f31de
--- /dev/null
+++ b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
@@ -0,0 +1,116 @@
+<script>
+import _ from 'lodash';
+import { __ } from '../../locale';
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import { APPLICATION_STATUS, INGRESS } from '~/clusters/constants';
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import eventHub from '~/clusters/event_hub';
+
+const { UPDATING, UNINSTALLING } = APPLICATION_STATUS;
+
+export default {
+ components: {
+ LoadingButton,
+ GlAlert,
+ GlSprintf,
+ GlLink,
+ },
+ props: {
+ ingress: {
+ type: Object,
+ required: true,
+ },
+ ingressModSecurityHelpPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ modSecurityEnabled: {
+ get() {
+ return this.ingress.modsecurity_enabled;
+ },
+ set(isEnabled) {
+ eventHub.$emit('setIngressModSecurityEnabled', {
+ id: INGRESS,
+ modSecurityEnabled: isEnabled,
+ });
+ },
+ },
+ ingressModSecurityDescription() {
+ return _.escape(this.ingressModSecurityHelpPath);
+ },
+ saving() {
+ return [UPDATING].includes(this.ingress.status);
+ },
+ saveButtonDisabled() {
+ return [UNINSTALLING, UPDATING].includes(this.ingress.status);
+ },
+ saveButtonLabel() {
+ return this.saving ? __('Saving') : __('Save changes');
+ },
+ ingressInstalled() {
+ return this.ingress.installed;
+ },
+ },
+ methods: {
+ updateApplication() {
+ eventHub.$emit('updateApplication', {
+ id: INGRESS,
+ params: { modsecurity_enabled: this.ingress.modsecurity_enabled },
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-alert
+ v-if="ingress.updateFailed"
+ class="mb-3"
+ variant="danger"
+ :dismissible="false"
+ @dismiss="alert = null"
+ >
+ {{
+ s__('ClusterIntegration|Something went wrong while updating the Web Application Firewall.')
+ }}
+ </gl-alert>
+ <div class="form-group">
+ <div class="form-check form-check-inline">
+ <input
+ v-model="modSecurityEnabled"
+ type="checkbox"
+ autocomplete="off"
+ class="form-check-input"
+ />
+ <label class="form-check-label label-bold" for="ingress-enable-modsecurity">
+ {{ s__('ClusterIntegration|Enable Web Application Firewall') }}
+ </label>
+ </div>
+ <p class="form-text text-muted">
+ <strong>
+ <gl-sprintf
+ :message="s__('ClusterIntegration|Learn more about %{linkStart}ModSecurity%{linkEnd}')"
+ >
+ <template #link="{ content }">
+ <gl-link :href="ingressModSecurityDescription" target="_blank"
+ >{{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </strong>
+ </p>
+ <loading-button
+ v-if="ingressInstalled"
+ class="btn-success mt-1"
+ :loading="saving"
+ :disabled="saveButtonDisabled"
+ :label="saveButtonLabel"
+ @click="updateApplication"
+ />
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js
index 939c396e1b9..ffe71455b2d 100644
--- a/app/assets/javascripts/clusters/stores/clusters_store.js
+++ b/app/assets/javascripts/clusters/stores/clusters_store.js
@@ -54,6 +54,8 @@ export default class ClusterStore {
modsecurity_enabled: false,
externalIp: null,
externalHostname: null,
+ isEditingModSecurityEnabled: false,
+ updateFailed: false,
},
cert_manager: {
...applicationInitialState,
@@ -208,8 +210,11 @@ export default class ClusterStore {
if (appId === INGRESS) {
this.state.applications.ingress.externalIp = serverAppEntry.external_ip;
this.state.applications.ingress.externalHostname = serverAppEntry.external_hostname;
- this.state.applications.ingress.modsecurity_enabled =
- serverAppEntry.modsecurity_enabled || this.state.applications.ingress.modsecurity_enabled;
+ if (!this.state.applications.ingress.isEditingModSecurityEnabled) {
+ this.state.applications.ingress.modsecurity_enabled =
+ serverAppEntry.modsecurity_enabled ||
+ this.state.applications.ingress.modsecurity_enabled;
+ }
} else if (appId === CERT_MANAGER) {
this.state.applications.cert_manager.email =
this.state.applications.cert_manager.email || serverAppEntry.email;
diff --git a/app/assets/javascripts/repository/components/preview/index.vue b/app/assets/javascripts/repository/components/preview/index.vue
index 2bc93c3f1c1..78ae719ba0d 100644
--- a/app/assets/javascripts/repository/components/preview/index.vue
+++ b/app/assets/javascripts/repository/components/preview/index.vue
@@ -1,4 +1,6 @@
<script>
+import $ from 'jquery';
+import '~/behaviors/markdown/render_gfm';
import { GlLink, GlLoadingIcon } from '@gitlab/ui';
import getReadmeQuery from '../../queries/getReadme.query.graphql';
@@ -30,6 +32,15 @@ export default {
loading: 0,
};
},
+ watch: {
+ readme(newVal) {
+ if (newVal) {
+ this.$nextTick(() => {
+ $(this.$refs.readme).renderGFM();
+ });
+ }
+ },
+ },
};
</script>
@@ -45,7 +56,7 @@ export default {
</div>
<div class="blob-viewer">
<gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
- <div v-else-if="readme" v-html="readme.html"></div>
+ <div v-else-if="readme" ref="readme" v-html="readme.html"></div>
</div>
</article>
</template>
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 41f3603506f..005e5efbdaf 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -150,6 +150,12 @@
right: 8px;
}
+ .spinner {
+ position: absolute;
+ top: 9px;
+ right: 8px;
+ }
+
.ic-chevron-down {
position: absolute;
top: $gl-padding-8;
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 958dc27984f..80c7a803392 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -97,7 +97,7 @@ class GroupsController < Groups::ApplicationController
end
def edit
- @badge_api_endpoint = expose_url(api_v4_groups_badges_path(id: @group.id))
+ @badge_api_endpoint = expose_path(api_v4_groups_badges_path(id: @group.id))
end
def projects
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 31b86946ca2..045aa38230c 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -50,7 +50,7 @@ class ProjectsController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def edit
- @badge_api_endpoint = expose_url(api_v4_projects_badges_path(id: @project.id))
+ @badge_api_endpoint = expose_path(api_v4_projects_badges_path(id: @project.id))
render_edit
end