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
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-09 15:06:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-09 15:06:13 +0300
commit0a850868dfb85086cba8320cee9dac4657dcae6c (patch)
tree40d17228fe23d9db7b861fe2a20d024d64c50323 /app
parent3744bcc0d10d24104e39985b6833a0ec51791c0a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/behaviors/markdown/editor_extensions.js2
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/audio.js53
-rw-r--r--app/assets/javascripts/blob/viewer/index.js6
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue4
-rw-r--r--app/assets/javascripts/clusters/components/knative_domain_editor.vue2
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue2
-rw-r--r--app/assets/javascripts/jobs/components/commit_block.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue88
-rw-r--r--app/assets/javascripts/monitoring/components/graph_group.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/panel_type.vue2
-rw-r--r--app/assets/javascripts/registry/components/app.vue4
-rw-r--r--app/assets/javascripts/repository/components/last_commit.vue2
-rw-r--r--app/assets/javascripts/serverless/components/url.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/clipboard_button.vue2
-rw-r--r--app/assets/stylesheets/pages/prometheus.scss35
-rw-r--r--app/controllers/concerns/uploads_actions.rb6
-rw-r--r--app/controllers/groups/uploads_controller.rb2
-rw-r--r--app/controllers/help_controller.rb4
-rw-r--r--app/controllers/projects/uploads_controller.rb2
-rw-r--r--app/helpers/blob_helper.rb4
-rw-r--r--app/helpers/button_helper.rb2
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/models/application_setting_implementation.rb3
-rw-r--r--app/models/blob.rb4
-rw-r--r--app/models/commit.rb2
-rw-r--r--app/views/admin/application_settings/network.html.haml2
-rw-r--r--app/views/admin/applications/show.html.haml4
-rw-r--r--app/views/admin/impersonation_tokens/index.html.haml2
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml4
-rw-r--r--app/views/doorkeeper/applications/show.html.haml4
-rw-r--r--app/views/projects/_new_project_push_tip.html.haml2
-rw-r--r--app/views/projects/buttons/_clone.html.haml4
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/deploy_tokens/_new_deploy_token.html.haml4
-rw-r--r--app/views/projects/merge_requests/_how_to_merge.html.haml6
-rw-r--r--app/views/projects/notes/_more_actions_dropdown.html.haml2
-rw-r--r--app/views/projects/pipelines/_info.html.haml2
-rw-r--r--app/views/projects/triggers/_trigger.html.haml2
-rw-r--r--app/views/shared/_clone_panel.html.haml2
-rw-r--r--app/views/shared/_personal_access_tokens_created_container.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml4
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--app/views/shared/snippets/_header.html.haml2
47 files changed, 226 insertions, 75 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/editor_extensions.js b/app/assets/javascripts/behaviors/markdown/editor_extensions.js
index 47e5fc65c48..8bd2145db1c 100644
--- a/app/assets/javascripts/behaviors/markdown/editor_extensions.js
+++ b/app/assets/javascripts/behaviors/markdown/editor_extensions.js
@@ -21,6 +21,7 @@ import Reference from './nodes/reference';
import TableOfContents from './nodes/table_of_contents';
import Video from './nodes/video';
+import Audio from './nodes/audio';
import BulletList from './nodes/bullet_list';
import OrderedList from './nodes/ordered_list';
@@ -78,6 +79,7 @@ export default [
new TableOfContents(),
new Video(),
+ new Audio(),
new BulletList(),
new OrderedList(),
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/audio.js b/app/assets/javascripts/behaviors/markdown/nodes/audio.js
new file mode 100644
index 00000000000..48ac408cf24
--- /dev/null
+++ b/app/assets/javascripts/behaviors/markdown/nodes/audio.js
@@ -0,0 +1,53 @@
+/* eslint-disable class-methods-use-this */
+
+import { Node } from 'tiptap';
+import { defaultMarkdownSerializer } from 'prosemirror-markdown';
+
+// Transforms generated HTML back to GFM for Banzai::Filter::AudioLinkFilter
+export default class Audio extends Node {
+ get name() {
+ return 'audio';
+ }
+
+ get schema() {
+ return {
+ attrs: {
+ src: {},
+ alt: {
+ default: null,
+ },
+ },
+ group: 'block',
+ draggable: true,
+ parseDOM: [
+ {
+ tag: '.audio-container',
+ skip: true,
+ },
+ {
+ tag: '.audio-container p',
+ priority: 51,
+ ignore: true,
+ },
+ {
+ tag: 'audio[src]',
+ getAttrs: el => ({ src: el.getAttribute('src'), alt: el.dataset.title }),
+ },
+ ],
+ toDOM: node => [
+ 'audio',
+ {
+ src: node.attrs.src,
+ controls: true,
+ 'data-setup': '{}',
+ 'data-title': node.attrs.alt,
+ },
+ ],
+ };
+ }
+
+ toMarkdown(state, node) {
+ defaultMarkdownSerializer.nodes.image(state, node);
+ state.closeBlock(node);
+ }
+}
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js
index 9ea455069f3..07e4dde41d9 100644
--- a/app/assets/javascripts/blob/viewer/index.js
+++ b/app/assets/javascripts/blob/viewer/index.js
@@ -107,18 +107,18 @@ export default class BlobViewer {
toggleCopyButtonState() {
if (!this.copySourceBtn) return;
if (this.simpleViewer.getAttribute('data-loaded')) {
- this.copySourceBtn.setAttribute('title', __('Copy source to clipboard'));
+ this.copySourceBtn.setAttribute('title', __('Copy file contents'));
this.copySourceBtn.classList.remove('disabled');
} else if (this.activeViewer === this.simpleViewer) {
this.copySourceBtn.setAttribute(
'title',
- __('Wait for the source to load to copy it to the clipboard'),
+ __('Wait for the file to load to copy its contents'),
);
this.copySourceBtn.classList.add('disabled');
} else {
this.copySourceBtn.setAttribute(
'title',
- __('Switch to the source to copy it to the clipboard'),
+ __('Switch to the source to copy the file contents'),
);
this.copySourceBtn.classList.add('disabled');
}
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index 4d3e759d8d4..b95f97077f6 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -294,7 +294,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="ingressExternalEndpoint"
- :title="s__('ClusterIntegration|Copy Ingress Endpoint to clipboard')"
+ :title="s__('ClusterIntegration|Copy Ingress Endpoint')"
class="input-group-text js-clipboard-btn"
/>
</span>
@@ -472,7 +472,7 @@ export default {
<span class="input-group-btn">
<clipboard-button
:text="jupyterHostname"
- :title="s__('ClusterIntegration|Copy Jupyter Hostname to clipboard')"
+ :title="s__('ClusterIntegration|Copy Jupyter Hostname')"
class="js-clipboard-btn"
/>
</span>
diff --git a/app/assets/javascripts/clusters/components/knative_domain_editor.vue b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
index e26ef135bc5..25347b11b6c 100644
--- a/app/assets/javascripts/clusters/components/knative_domain_editor.vue
+++ b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
@@ -103,7 +103,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="knativeExternalEndpoint"
- :title="s__('ClusterIntegration|Copy Knative Endpoint to clipboard')"
+ :title="s__('ClusterIntegration|Copy Knative Endpoint')"
class="input-group-text js-knative-endpoint-clipboard-btn"
/>
</span>
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index 761fd1583ed..43a7703f611 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -121,7 +121,7 @@ export default {
<div class="label label-monospace monospace" v-text="commit.short_id"></div>
<clipboard-button
:text="commit.id"
- :title="__('Copy commit SHA to clipboard')"
+ :title="__('Copy commit SHA')"
class="btn btn-default"
/>
</div>
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index bfcc726a030..665328eb234 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -209,7 +209,7 @@ export default {
</a>
<clipboard-button
- :title="__('Copy file path to clipboard')"
+ :title="__('Copy file path')"
:text="diffFile.file_path"
:gfm="gfmCopyText"
css-class="btn-default btn-transparent btn-clipboard"
diff --git a/app/assets/javascripts/jobs/components/commit_block.vue b/app/assets/javascripts/jobs/components/commit_block.vue
index 9fac880c5f8..8156f26ffb1 100644
--- a/app/assets/javascripts/jobs/components/commit_block.vue
+++ b/app/assets/javascripts/jobs/components/commit_block.vue
@@ -41,7 +41,7 @@ export default {
<clipboard-button
:text="commit.id"
- :title="__('Copy commit SHA to clipboard')"
+ :title="__('Copy commit SHA')"
css-class="btn btn-clipboard btn-transparent"
/>
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 084f736911f..9ecb9324f8c 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -1,4 +1,7 @@
<script>
+import _ from 'underscore';
+import { mapActions, mapState } from 'vuex';
+import VueDraggable from 'vuedraggable';
import {
GlButton,
GlDropdown,
@@ -8,8 +11,6 @@ import {
GlModalDirective,
GlTooltipDirective,
} from '@gitlab/ui';
-import _ from 'underscore';
-import { mapActions, mapState } from 'vuex';
import { __, s__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import { getParameterValues, mergeUrlParams } from '~/lib/utils/url_utility';
@@ -26,6 +27,7 @@ let sidebarMutationObserver;
export default {
components: {
+ VueDraggable,
MonitorTimeSeriesChart,
MonitorSingleStatChart,
PanelType,
@@ -151,6 +153,11 @@ export default {
required: false,
default: false,
},
+ rearrangePanelsAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -160,6 +167,7 @@ export default {
selectedTimeWindowKey: '',
formIsValid: null,
timeWindows: {},
+ isRearrangingPanels: false,
};
},
computed: {
@@ -183,6 +191,9 @@ export default {
selectedDashboardText() {
return this.currentDashboard || this.firstDashboard.display_name;
},
+ showRearrangePanelsBtn() {
+ return !this.showEmptyState && this.rearrangePanelsAvailable;
+ },
addingMetricsAvailable() {
return IS_EE && this.canAddMetrics && !this.showEmptyState;
},
@@ -271,9 +282,14 @@ export default {
return Object.values(this.getGraphAlerts(queries));
},
showToast() {
- this.$toast.show(__('Link copied to clipboard'));
+ this.$toast.show(__('Link copied'));
},
// TODO: END
+ removeGraph(metrics, graphIndex) {
+ // At present graphs will not be removed, they should removed using the vuex store
+ // See https://gitlab.com/gitlab-org/gitlab/issues/27835
+ metrics.splice(graphIndex, 1);
+ },
generateLink(group, title, yLabel) {
const dashboard = this.currentDashboard || this.firstDashboard.path;
const params = _.pick({ dashboard, group, title, y_label: yLabel }, value => value != null);
@@ -287,6 +303,9 @@ export default {
this.elWidth = this.$el.clientWidth;
}, sidebarAnimationDuration);
},
+ toggleRearrangingPanels() {
+ this.isRearrangingPanels = !this.isRearrangingPanels;
+ },
setFormValidity(isValid) {
this.formIsValid = isValid;
},
@@ -389,15 +408,27 @@ export default {
</template>
<gl-form-group
- v-if="addingMetricsAvailable || externalDashboardUrl.length"
+ v-if="addingMetricsAvailable || showRearrangePanelsBtn || externalDashboardUrl.length"
label-for="prometheus-graphs-dropdown-buttons"
class="dropdown-buttons col-lg d-lg-flex align-items-end"
>
<div id="prometheus-graphs-dropdown-buttons">
<gl-button
+ v-if="showRearrangePanelsBtn"
+ :pressed="isRearrangingPanels"
+ new-style
+ variant="default"
+ class="mr-2 mt-1 js-rearrange-button"
+ @click="toggleRearrangingPanels"
+ >
+ {{ __('Arrange charts') }}
+ </gl-button>
+ <gl-button
v-if="addingMetricsAvailable"
v-gl-modal="$options.addMetric.modalId"
- class="mr-2 mt-1 js-add-metric-button text-success border-success"
+ new-style
+ variant="outline-success"
+ class="mr-2 mt-1 js-add-metric-button"
>
{{ $options.addMetric.title }}
</gl-button>
@@ -451,17 +482,42 @@ export default {
:collapse-group="groupHasData(groupData)"
>
<template v-if="additionalPanelTypesEnabled">
- <panel-type
- v-for="(graphData, graphIndex) in groupData.metrics"
- :key="`panel-type-${graphIndex}`"
- class="col-12 col-lg-6 pb-3"
- :clipboard-text="generateLink(groupData.group, graphData.title, graphData.y_label)"
- :graph-data="graphData"
- :dashboard-width="elWidth"
- :alerts-endpoint="alertsEndpoint"
- :prometheus-alerts-available="prometheusAlertsAvailable"
- :index="`${index}-${graphIndex}`"
- />
+ <vue-draggable
+ :list="groupData.metrics"
+ group="metrics-dashboard"
+ :component-data="{ attrs: { class: 'row mx-0 w-100' } }"
+ :disabled="!isRearrangingPanels"
+ >
+ <div
+ v-for="(graphData, graphIndex) in groupData.metrics"
+ :key="`panel-type-${graphIndex}`"
+ class="col-12 col-lg-6 px-2 mb-2 draggable"
+ :class="{ 'draggable-enabled': isRearrangingPanels }"
+ >
+ <div class="position-relative draggable-panel js-draggable-panel">
+ <div
+ v-if="isRearrangingPanels"
+ class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end"
+ @click="removeGraph(groupData.metrics, graphIndex)"
+ >
+ <a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"
+ ><icon name="close"
+ /></a>
+ </div>
+
+ <panel-type
+ :clipboard-text="
+ generateLink(groupData.group, graphData.title, graphData.y_label)
+ "
+ :graph-data="graphData"
+ :dashboard-width="elWidth"
+ :alerts-endpoint="alertsEndpoint"
+ :prometheus-alerts-available="prometheusAlertsAvailable"
+ :index="`${index}-${graphIndex}`"
+ />
+ </div>
+ </div>
+ </vue-draggable>
</template>
<template v-else>
<monitor-time-series-chart
diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue
index 72ddd8d4fcf..ee3a2bae79b 100644
--- a/app/assets/javascripts/monitoring/components/graph_group.vue
+++ b/app/assets/javascripts/monitoring/components/graph_group.vue
@@ -52,7 +52,7 @@ export default {
<div
v-if="collapseGroup"
v-show="collapseGroup && showGroup"
- class="card-body prometheus-graph-group"
+ class="card-body prometheus-graph-group p-0"
>
<slot></slot>
</div>
diff --git a/app/assets/javascripts/monitoring/components/panel_type.vue b/app/assets/javascripts/monitoring/components/panel_type.vue
index 73ff651d510..af0d8335c43 100644
--- a/app/assets/javascripts/monitoring/components/panel_type.vue
+++ b/app/assets/javascripts/monitoring/components/panel_type.vue
@@ -82,7 +82,7 @@ export default {
return this.graphData.type && this.graphData.type === type;
},
showToast() {
- this.$toast.show(__('Link copied to clipboard'));
+ this.$toast.show(__('Link copied'));
},
},
};
diff --git a/app/assets/javascripts/registry/components/app.vue b/app/assets/javascripts/registry/components/app.vue
index 60aaef656a0..7ae06af02cf 100644
--- a/app/assets/javascripts/registry/components/app.vue
+++ b/app/assets/javascripts/registry/components/app.vue
@@ -143,7 +143,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="dockerBuildCommand"
- :title="s__('ContainerRegistry|Copy build command to clipboard')"
+ :title="s__('ContainerRegistry|Copy build command')"
class="input-group-text"
/>
</span>
@@ -154,7 +154,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="dockerPushCommand"
- :title="s__('ContainerRegistry|Copy push command to clipboard')"
+ :title="s__('ContainerRegistry|Copy push command')"
class="input-group-text"
/>
</span>
diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue
index 1b023f13862..19a2db2db25 100644
--- a/app/assets/javascripts/repository/components/last_commit.vue
+++ b/app/assets/javascripts/repository/components/last_commit.vue
@@ -144,7 +144,7 @@ export default {
</div>
<clipboard-button
:text="commit.sha"
- :title="__('Copy commit SHA to clipboard')"
+ :title="__('Copy commit SHA')"
tooltip-placement="bottom"
/>
</div>
diff --git a/app/assets/javascripts/serverless/components/url.vue b/app/assets/javascripts/serverless/components/url.vue
index e47a03f1939..5e30c8d614e 100644
--- a/app/assets/javascripts/serverless/components/url.vue
+++ b/app/assets/javascripts/serverless/components/url.vue
@@ -23,7 +23,7 @@ export default {
<div class="url-text-field label label-monospace monospace">{{ uri }}</div>
<clipboard-button
:text="uri"
- :title="s__('ServerlessURL|Copy URL to clipboard')"
+ :title="s__('ServerlessURL|Copy URL')"
class="input-group-text js-clipboard-btn"
/>
<gl-button
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index fb826be19f5..2aaba6e1c8a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -90,7 +90,7 @@ export default {
v-html="mr.sourceBranchLink"
/><clipboard-button
:text="branchNameClipboardData"
- :title="__('Copy branch name to clipboard')"
+ :title="__('Copy branch name')"
css-class="btn-default btn-transparent btn-clipboard"
/>
{{ s__('mrWidget|into') }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
index fb07c03e34d..a2b5a79af36 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
@@ -170,7 +170,7 @@ export default {
>
</a>
<clipboard-button
- :title="__('Copy commit SHA to clipboard')"
+ :title="__('Copy commit SHA')"
:text="mr.mergeCommitSha"
css-class="btn-default btn-transparent btn-clipboard js-mr-merged-copy-sha"
/>
diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue
index a620f560b52..9f498037185 100644
--- a/app/assets/javascripts/vue_shared/components/clipboard_button.vue
+++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue
@@ -7,7 +7,7 @@
*
* @example
* <clipboard-button
- * title="Copy to clipboard"
+ * title="Copy"
* text="Content to be copied"
* css-class="btn-transparent"
* />
diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss
index 245efd91ec8..ceafff94719 100644
--- a/app/assets/stylesheets/pages/prometheus.scss
+++ b/app/assets/stylesheets/pages/prometheus.scss
@@ -15,6 +15,37 @@
}
}
+.draggable {
+ &.draggable-enabled {
+ .draggable-panel {
+ border: $gray-200 1px solid;
+ border-radius: $border-radius-default;
+ margin: -1px;
+ cursor: grab;
+ }
+
+ .prometheus-graph {
+ // Make dragging easier by disabling use of chart
+ pointer-events: none;
+ }
+ }
+
+ &.sortable-chosen .draggable-panel {
+ background: $white-light;
+ box-shadow: 0 0 4px $gray-500;
+ }
+
+ .draggable-remove {
+ z-index: 1;
+
+ .draggable-remove-link {
+ cursor: pointer;
+ color: $gray-600;
+ background-color: $white-light;
+ }
+ }
+}
+
.prometheus-panel {
margin-top: 20px;
}
@@ -22,11 +53,11 @@
.prometheus-graph-group {
display: flex;
flex-wrap: wrap;
- padding: $gl-padding / 2;
+ margin-top: $gl-padding-8;
}
.prometheus-graph {
- padding: $gl-padding / 2;
+ padding: $gl-padding-8;
}
.prometheus-graph-embed {
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index 79bee6f89d8..77afffc4b27 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -37,7 +37,7 @@ module UploadsActions
expires_in 0.seconds, must_revalidate: true, private: true
end
- disposition = uploader.image_or_video? ? 'inline' : 'attachment'
+ disposition = uploader.embeddable? ? 'inline' : 'attachment'
uploaders = [uploader, *uploader.versions.values]
uploader = uploaders.find { |version| version.filename == params[:filename] }
@@ -112,8 +112,8 @@ module UploadsActions
uploader
end
- def image_or_video?
- uploader && uploader.exists? && uploader.image_or_video?
+ def embeddable?
+ uploader && uploader.exists? && uploader.embeddable?
end
def find_model
diff --git a/app/controllers/groups/uploads_controller.rb b/app/controllers/groups/uploads_controller.rb
index 7e5cdae0ce3..3ae7e36c740 100644
--- a/app/controllers/groups/uploads_controller.rb
+++ b/app/controllers/groups/uploads_controller.rb
@@ -4,7 +4,7 @@ class Groups::UploadsController < Groups::ApplicationController
include UploadsActions
include WorkhorseRequest
- skip_before_action :group, if: -> { action_name == 'show' && image_or_video? }
+ skip_before_action :group, if: -> { action_name == 'show' && embeddable? }
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 837c26c630a..a58235790ad 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -40,8 +40,8 @@ class HelpController < ApplicationController
end
end
- # Allow access to images in the doc folder
- format.any(:png, :gif, :jpeg, :mp4) do
+ # Allow access to specific media files in the doc folder
+ format.any(:png, :gif, :jpeg, :mp4, :mp3) do
# Note: We are purposefully NOT using `Rails.root.join`
path = File.join(Rails.root, 'doc', "#{@path}.#{params[:format]}")
diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb
index 4ffcc2ac805..3e5a1cfc74d 100644
--- a/app/controllers/projects/uploads_controller.rb
+++ b/app/controllers/projects/uploads_controller.rb
@@ -6,7 +6,7 @@ class Projects::UploadsController < Projects::ApplicationController
# These will kick you out if you don't have access.
skip_before_action :project, :repository,
- if: -> { action_name == 'show' && image_or_video? }
+ if: -> { action_name == 'show' && embeddable? }
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 4b0713001a1..6d1ec16b0c2 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -197,13 +197,13 @@ module BlobHelper
end
def copy_file_path_button(file_path)
- clipboard_button(text: file_path, gfm: "`#{file_path}`", class: 'btn-clipboard btn-transparent', title: 'Copy file path to clipboard')
+ clipboard_button(text: file_path, gfm: "`#{file_path}`", class: 'btn-clipboard btn-transparent', title: _('Copy file path'))
end
def copy_blob_source_button(blob)
return unless blob.rendered_as_text?(ignore_errors: false)
- clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: "Copy source to clipboard")
+ clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: _("Copy file contents"))
end
def open_raw_blob_button(blob)
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index 12cd5403f71..610d823dd3c 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -21,7 +21,7 @@ module ButtonHelper
# See http://clipboardjs.com/#usage
def clipboard_button(data = {})
css_class = data[:class] || 'btn-clipboard btn-transparent'
- title = data[:title] || _('Copy to clipboard')
+ title = data[:title] || _('Copy')
button_text = data[:button_text] || ''
hide_tooltip = data[:hide_tooltip] || false
hide_button_icon = data[:hide_button_icon] || false
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index c65611b7efc..9a19758b4e8 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -79,7 +79,7 @@ module SearchHelper
def search_entries_empty_message(scope, term)
(s_("SearchResults|We couldn't find any %{scope} matching %{term}") % {
scope: search_entries_scope_label(scope, 0),
- term: "<code>#{term}</code>"
+ term: "<code>#{h(term)}</code>"
}).html_safe
end
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index d486347bb1d..e2579316fdd 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -109,6 +109,9 @@ module ApplicationSettingImplementation
throttle_protected_paths_in_seconds: 10,
throttle_protected_paths_per_period: 60,
protected_paths: DEFAULT_PROTECTED_PATHS,
+ throttle_incident_management_notification_enabled: false,
+ throttle_incident_management_notification_period_in_seconds: 3600,
+ throttle_incident_management_notification_per_period: 3600,
time_tracking_limit_to_hours: false,
two_factor_grace_period: 48,
unique_ips_limit_enabled: false,
diff --git a/app/models/blob.rb b/app/models/blob.rb
index 137dfb484e0..1495aed6598 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -179,6 +179,10 @@ class Blob < SimpleDelegator
UploaderHelper::SAFE_VIDEO_EXT.include?(extension)
end
+ def audio?
+ UploaderHelper::SAFE_AUDIO_EXT.include?(extension)
+ end
+
def readable_text?
text_in_repo? && !stored_externally? && !truncated?
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 60a60f191d6..57069280ef7 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -415,7 +415,7 @@ class Commit
if entry[:type] == :blob
blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), @project)
- blob.image? || blob.video? ? :raw : :blob
+ blob.image? || blob.video? || blob.audio? ? :raw : :blob
else
entry[:type]
end
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index a1f39e22e80..092834b993c 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -45,3 +45,5 @@
= _('Configure paths to be protected by Rack Attack. A web server restart is required after changing these settings.')
.settings-content
= render 'protected_paths'
+
+= render_if_exists 'admin/application_settings/ee_network_settings'
diff --git a/app/views/admin/applications/show.html.haml b/app/views/admin/applications/show.html.haml
index 180066723f1..aca9302aff7 100644
--- a/app/views/admin/applications/show.html.haml
+++ b/app/views/admin/applications/show.html.haml
@@ -13,7 +13,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
.input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "btn btn btn-default")
%tr
%td
= _('Secret')
@@ -22,7 +22,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
.input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#secret', title: _("Copy secret"), class: "btn btn btn-default")
%tr
%td
= _('Callback URL')
diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml
index 8e869fb4b71..a7da14d16ff 100644
--- a/app/views/admin/impersonation_tokens/index.html.haml
+++ b/app/views/admin/impersonation_tokens/index.html.haml
@@ -8,7 +8,7 @@
- if @new_impersonation_token
= render "shared/personal_access_tokens_created_container", new_token_value: @new_impersonation_token,
container_title: 'Your New Impersonation Token',
- clipboard_button_title: 'Copy impersonation token to clipboard'
+ clipboard_button_title: _('Copy impersonation token')
= render "shared/personal_access_tokens_form", path: admin_user_impersonation_tokens_path, impersonation: true, token: @impersonation_token, scopes: @scopes
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 4307060d748..aca8aa5d341 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -8,11 +8,11 @@
%li
= _("Specify the following URL during the Runner setup:")
%code#coordinator_address= root_url(only_path: false)
- = clipboard_button(target: '#coordinator_address', title: _("Copy URL to clipboard"), class: "btn-transparent btn-clipboard")
+ = clipboard_button(target: '#coordinator_address', title: _("Copy URL"), class: "btn-transparent btn-clipboard")
%li
= _("Use the following registration token during setup:")
%code#registration_token= registration_token
- = clipboard_button(target: '#registration_token', title: _("Copy token to clipboard"), class: "btn-transparent btn-clipboard")
+ = clipboard_button(target: '#registration_token', title: _("Copy token"), class: "btn-transparent btn-clipboard")
.prepend-top-10.append-bottom-10
= button_to _("Reset runners registration token"), reset_token_url,
method: :put, class: 'btn btn-default',
diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml
index 6750732ab67..8a1b7500abf 100644
--- a/app/views/doorkeeper/applications/show.html.haml
+++ b/app/views/doorkeeper/applications/show.html.haml
@@ -16,7 +16,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "application_id", type: "text", autocomplete: 'off', value: @application.uid, readonly: true }
.input-group-append
- = clipboard_button(target: '#application_id', title: _("Copy ID to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#application_id', title: _("Copy ID"), class: "btn btn btn-default")
%tr
%td
= _('Secret')
@@ -25,7 +25,7 @@
.input-group
%input.label.label-monospace.monospace{ id: "secret", type: "text", autocomplete: 'off', value: @application.secret, readonly: true }
.input-group-append
- = clipboard_button(target: '#secret', title: _("Copy secret to clipboard"), class: "btn btn btn-default")
+ = clipboard_button(target: '#secret', title: _("Copy secret"), class: "btn btn btn-default")
%tr
%td
= _('Callback URL')
diff --git a/app/views/projects/_new_project_push_tip.html.haml b/app/views/projects/_new_project_push_tip.html.haml
index 22e9522c0e7..e008130436c 100644
--- a/app/views/projects/_new_project_push_tip.html.haml
+++ b/app/views/projects/_new_project_push_tip.html.haml
@@ -6,6 +6,6 @@
%span
= text_field_tag :push_to_create_tip, push_to_create_project_command, class: "js-select-on-focus form-control monospace", readonly: true, aria: { label: _("Push project from command line") }
%span.input-group-append
- = clipboard_button(text: push_to_create_project_command, title: _("Copy command to clipboard"), class: 'input-group-text', placement: "right")
+ = clipboard_button(text: push_to_create_project_command, title: _("Copy command"), class: 'input-group-text', placement: "right")
%p
= link_to("What does this command do?", help_page_path("gitlab-basics/create-project", anchor: "push-to-create-a-new-project"), target: "_blank")
diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml
index 09f05b30433..abef33ca01c 100644
--- a/app/views/projects/buttons/_clone.html.haml
+++ b/app/views/projects/buttons/_clone.html.haml
@@ -13,7 +13,7 @@
.input-group
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control qa-ssh-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
- if http_enabled?
%li.pt-2
@@ -22,7 +22,7 @@
.input-group
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control qa-http-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = clipboard_button(target: '#http_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
= render_if_exists 'projects/buttons/kerberos_clone_field'
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 6c77036a85b..d07407a6d13 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -6,7 +6,7 @@
%strong
#{ s_('CommitBoxTitle|Commit') }
%span.commit-sha{ data: { qa_selector: 'commit_sha_content' } }= @commit.short_id
- = clipboard_button(text: @commit.id, title: _('Copy commit SHA to clipboard'))
+ = clipboard_button(text: @commit.id, title: _('Copy commit SHA'))
%span.d-none.d-sm-inline= _('authored')
#{time_ago_with_tooltip(@commit.authored_date)}
%span= s_('ByAuthor|by')
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 0f913d11be1..3a9c7a8bec5 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -56,5 +56,5 @@
.commit-sha-group.d-none.d-sm-flex
.label.label-monospace.monospace
= commit.short_id
- = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"), class: "btn btn-default", container: "body")
+ = clipboard_button(text: commit.id, title: _("Copy commit SHA"), class: "btn btn-default", container: "body")
= link_to_browse_code(project, commit)
diff --git a/app/views/projects/deploy_tokens/_new_deploy_token.html.haml b/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
index c805ee73acc..f295fa82192 100644
--- a/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
+++ b/app/views/projects/deploy_tokens/_new_deploy_token.html.haml
@@ -7,12 +7,12 @@
.input-group
= text_field_tag 'deploy-token-user', deploy_token.username, readonly: true, class: 'deploy-token-field form-control js-select-on-focus qa-deploy-token-user'
.input-group-append
- = clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username to clipboard'), placement: 'left')
+ = clipboard_button(text: deploy_token.username, title: s_('DeployTokens|Copy username'), placement: 'left')
%span.deploy-token-help-block.prepend-top-5.text-success= s_("DeployTokens|Use this username as a login.")
.form-group
.input-group
= text_field_tag 'deploy-token', deploy_token.token, readonly: true, class: 'deploy-token-field form-control js-select-on-focus qa-deploy-token'
.input-group-append
- = clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token to clipboard'), placement: 'left')
+ = clipboard_button(text: deploy_token.token, title: s_('DeployTokens|Copy deploy token'), placement: 'left')
%span.deploy-token-help-block.prepend-top-5.text-danger= s_("DeployTokens|Use this token as a password. Make sure you save it - you won't be able to access it again.")
diff --git a/app/views/projects/merge_requests/_how_to_merge.html.haml b/app/views/projects/merge_requests/_how_to_merge.html.haml
index 928b54ea28f..57205682bda 100644
--- a/app/views/projects/merge_requests/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/_how_to_merge.html.haml
@@ -9,7 +9,7 @@
%p
%strong Step 1.
Fetch and check out the branch for this merge request
- = clipboard_button(target: "pre#merge-info-1", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-1", title: _("Copy commands"))
%pre.dark#merge-info-1
- if @merge_request.for_fork?
:preserve
@@ -27,7 +27,7 @@
%p
%strong Step 3.
Merge the branch and fix any conflicts that come up
- = clipboard_button(target: "pre#merge-info-3", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-3", title: _("Copy commands"))
%pre.dark#merge-info-3
- if @merge_request.for_fork?
:preserve
@@ -42,7 +42,7 @@
%p
%strong Step 4.
Push the result of the merge to GitLab
- = clipboard_button(target: "pre#merge-info-4", title: "Copy commands to clipboard")
+ = clipboard_button(target: "pre#merge-info-4", title: _("Copy commands"))
%pre.dark#merge-info-4
:preserve
git push origin "#{h @merge_request.target_branch}"
diff --git a/app/views/projects/notes/_more_actions_dropdown.html.haml b/app/views/projects/notes/_more_actions_dropdown.html.haml
index 8a6e5fde99b..2f0394538bb 100644
--- a/app/views/projects/notes/_more_actions_dropdown.html.haml
+++ b/app/views/projects/notes/_more_actions_dropdown.html.haml
@@ -7,7 +7,7 @@
= custom_icon('ellipsis_v')
%ul.dropdown-menu.more-actions-dropdown.dropdown-open-left
%li
- = clipboard_button(text: noteable_note_url(note), title: 'Copy reference to clipboard', button_text: 'Copy link', class: 'btn-clipboard', hide_tooltip: true, hide_button_icon: true)
+ = clipboard_button(text: noteable_note_url(note), title: _('Copy reference'), button_text: _('Copy link'), class: 'btn-clipboard', hide_tooltip: true, hide_button_icon: true)
- unless is_current_user
%li
= link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index 7187afc7754..094cbf755e1 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -58,4 +58,4 @@
= sprite_icon('ellipsis_h', size: 12)
%span.js-details-content.hide
= link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full"
- = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard")
+ = clipboard_button(text: @pipeline.sha, title: _("Copy commit SHA"))
diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml
index 9899cf9c6de..60de3630bb5 100644
--- a/app/views/projects/triggers/_trigger.html.haml
+++ b/app/views/projects/triggers/_trigger.html.haml
@@ -2,7 +2,7 @@
%td
- if trigger.has_token_exposed?
%span= trigger.token
- = clipboard_button(text: trigger.token, title: "Copy trigger token to clipboard")
+ = clipboard_button(text: trigger.token, title: _("Copy trigger token"))
- else
%span= trigger.short_token
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index 1e509ea0d1f..cb834878276 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -20,7 +20,7 @@
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
- = clipboard_button(target: '#project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
+ = clipboard_button(target: '#project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'shared/geo_modal_button'
diff --git a/app/views/shared/_personal_access_tokens_created_container.html.haml b/app/views/shared/_personal_access_tokens_created_container.html.haml
index 42989b145a2..df4577e2862 100644
--- a/app/views/shared/_personal_access_tokens_created_container.html.haml
+++ b/app/views/shared/_personal_access_tokens_created_container.html.haml
@@ -1,5 +1,5 @@
- container_title = local_assigns.fetch(:container_title, _('Your New Personal Access Token'))
-- clipboard_button_title = local_assigns.fetch(:clipboard_button_title, _('Copy personal access token to clipboard'))
+- clipboard_button_title = local_assigns.fetch(:clipboard_button_title, _('Copy personal access token'))
.created-personal-access-token-container
%h5.prepend-top-0
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 3b26b8df8a1..a55b7fc530a 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -148,13 +148,13 @@
- project_ref = issuable_sidebar[:reference]
.block.project-reference
.sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: project_ref, title: _('Copy reference to clipboard'), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
= _('Reference:')
%cite{ title: project_ref }
= project_ref
- = clipboard_button(text: project_ref, title: _('Copy reference to clipboard'), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
- if issuable_sidebar.dig(:current_user, :can_move)
.block.js-sidebar-move-issue-block
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index ced6af50501..22a6d5e33f0 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -142,10 +142,10 @@
- if milestone_ref.present?
.block.reference
.sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
Reference:
%cite{ title: milestone_ref }
= milestone_ref
- = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index 69481293f90..8d94a87a775 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -46,5 +46,5 @@
%strong.embed-toggle-list-item= _("Share")
%input.js-snippet-url-area.snippet-embed-input.form-control{ type: "text", autocomplete: 'off', value: snippet_embed }
.input-group-append
- = clipboard_button(title: s_('Copy to clipboard'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
+ = clipboard_button(title: _('Copy'), class: 'js-clipboard-btn snippet-clipboard-btn btn btn-default', target: '.js-snippet-url-area')
.clearfix