summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue')
-rw-r--r--app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue159
1 files changed, 159 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
new file mode 100644
index 00000000000..56e6399a1b7
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
@@ -0,0 +1,159 @@
+<script>
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ GlSprintf,
+} from '@gitlab/ui';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
+import { __, n__, s__, sprintf } from '~/locale';
+
+export const i18n = {
+ messageAdditionsDeletions: s__('Diffs|with %{additions} and %{deletions}'),
+ noFilesFound: __('No files found.'),
+ noFileNameAvailable: s__('Diffs|No file name available'),
+ searchFiles: __('Search files'),
+};
+
+export default {
+ i18n,
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ GlSprintf,
+ },
+ props: {
+ changed: {
+ type: Number,
+ required: true,
+ },
+ added: {
+ type: Number,
+ required: true,
+ },
+ deleted: {
+ type: Number,
+ required: true,
+ },
+ files: {
+ type: Array,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ search: '',
+ };
+ },
+ computed: {
+ filteredFiles() {
+ return this.search.length > 0
+ ? fuzzaldrinPlus.filter(this.files, this.search, { key: 'name' })
+ : this.files;
+ },
+ messageChanged() {
+ return sprintf(
+ n__(
+ 'Diffs|Showing %{dropdownStart}%{count} changed file%{dropdownEnd}',
+ 'Diffs|Showing %{dropdownStart}%{count} changed files%{dropdownEnd}',
+ this.changed,
+ ),
+ { count: this.changed },
+ );
+ },
+
+ additionsText() {
+ return n__('Diffs|%d addition', 'Diffs|%d additions', this.added);
+ },
+ deletionsText() {
+ return n__('Diffs|%d deletion', 'Diffs|%d deletions', this.deleted);
+ },
+ },
+ methods: {
+ jumpToFile(fileHash) {
+ window.location.hash = fileHash;
+ },
+ focusInput() {
+ this.$refs.search.focusInput();
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-sprintf :message="messageChanged">
+ <template #dropdown="{ content: dropdownText }">
+ <gl-dropdown
+ category="tertiary"
+ variant="confirm"
+ :text="dropdownText"
+ data-testid="diff-stats-dropdown"
+ class="gl-vertical-align-baseline"
+ toggle-class="gl-px-0! gl-font-weight-bold!"
+ menu-class="gl-w-auto!"
+ no-flip
+ @shown="focusInput"
+ >
+ <template #header>
+ <gl-search-box-by-type
+ ref="search"
+ v-model.trim="search"
+ :placeholder="$options.i18n.searchFiles"
+ />
+ </template>
+ <gl-dropdown-item
+ v-for="file in filteredFiles"
+ :key="file.href"
+ :icon-name="file.icon"
+ :icon-color="file.iconColor"
+ @click="jumpToFile(file.href)"
+ >
+ <div class="gl-display-flex">
+ <span v-if="file.name" class="gl-font-weight-bold gl-mr-3 gl-text-truncate">{{
+ file.name
+ }}</span>
+ <span v-else class="gl-mr-3 gl-font-weight-bold gl-font-style-italic gl-gray-400">{{
+ $options.i18n.noFileNameAvailable
+ }}</span>
+ <span class="gl-ml-auto gl-white-space-nowrap">
+ <span class="gl-text-green-600">+{{ file.added }}</span>
+ <span class="gl-text-red-500">-{{ file.removed }}</span>
+ </span>
+ </div>
+ <div class="gl-text-gray-700 gl-overflow-hidden gl-text-overflow-ellipsis">
+ {{ file.path }}
+ </div>
+ </gl-dropdown-item>
+ <gl-dropdown-text v-if="!filteredFiles.length">
+ {{ $options.i18n.noFilesFound }}
+ </gl-dropdown-text>
+ </gl-dropdown>
+ </template>
+ </gl-sprintf>
+ <span
+ class="diff-stats-additions-deletions-expanded"
+ data-testid="diff-stats-additions-deletions-expanded"
+ >
+ <gl-sprintf :message="$options.i18n.messageAdditionsDeletions">
+ <template #additions>
+ <span class="gl-text-green-600 gl-font-weight-bold">{{ additionsText }}</span>
+ </template>
+ <template #deletions>
+ <span class="gl-text-red-500 gl-font-weight-bold">{{ deletionsText }}</span>
+ </template>
+ </gl-sprintf>
+ </span>
+
+ <div
+ class="diff-stats-additions-deletions-collapsed gl-float-right gl-display-none"
+ data-testid="diff-stats-additions-deletions-collapsed"
+ >
+ <span class="gl-text-green-600 gl-font-weight-bold">+{{ added }}</span>
+ <span class="gl-text-red-500 gl-font-weight-bold">-{{ deleted }}</span>
+ </div>
+ </div>
+</template>