diff_file.vue 6.6 KB
Newer Older
F
Felipe Artur 已提交
1
<script>
2
/* eslint-disable vue/no-v-html */
3
import { mapActions, mapGetters, mapState } from 'vuex';
4
import { escape } from 'lodash';
5
import { GlLoadingIcon } from '@gitlab/ui';
6
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
F
Felipe Artur 已提交
7
import { __, sprintf } from '~/locale';
8
import { deprecatedCreateFlash as createFlash } from '~/flash';
9
import { hasDiff } from '~/helpers/diffs_helper';
10
import eventHub from '../../notes/event_hub';
F
Felipe Artur 已提交
11 12
import DiffFileHeader from './diff_file_header.vue';
import DiffContent from './diff_content.vue';
13
import { diffViewerErrors } from '~/ide/constants';
F
Felipe Artur 已提交
14 15 16 17 18

export default {
  components: {
    DiffFileHeader,
    DiffContent,
19
    GlLoadingIcon,
F
Felipe Artur 已提交
20
  },
21
  mixins: [glFeatureFlagsMixin()],
F
Felipe Artur 已提交
22 23 24 25 26
  props: {
    file: {
      type: Object,
      required: true,
    },
27 28
    canCurrentUserFork: {
      type: Boolean,
F
Felipe Artur 已提交
29 30
      required: true,
    },
31 32 33 34 35
    helpPagePath: {
      type: String,
      required: false,
      default: '',
    },
36 37 38 39
    viewDiffsFileByFile: {
      type: Boolean,
      required: true,
    },
F
Felipe Artur 已提交
40 41 42 43 44
  },
  data() {
    return {
      isLoadingCollapsedDiff: false,
      forkMessageVisible: false,
45
      isCollapsed: this.file.viewer.collapsed || false,
F
Felipe Artur 已提交
46 47 48
    };
  },
  computed: {
49
    ...mapState('diffs', ['currentDiffFileId']),
P
Phil Hughes 已提交
50
    ...mapGetters(['isNotesFetched']),
51
    ...mapGetters('diffs', ['getDiffFileDiscussions']),
F
Felipe Artur 已提交
52 53 54 55
    viewBlobLink() {
      return sprintf(
        __('You can %{linkStart}view the blob%{linkEnd} instead.'),
        {
56
          linkStart: `<a href="${escape(this.file.view_path)}">`,
F
Felipe Artur 已提交
57 58 59 60 61
          linkEnd: '</a>',
        },
        false,
      );
    },
62
    showLoadingIcon() {
P
Phil Hughes 已提交
63
      return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed);
64
    },
65
    hasDiff() {
66
      return hasDiff(this.file);
67
    },
68 69 70 71 72 73
    isFileTooLarge() {
      return this.file.viewer.error === diffViewerErrors.too_large;
    },
    errorMessage() {
      return this.file.viewer.error_message;
    },
A
André Luís 已提交
74 75 76 77 78 79 80 81 82 83 84 85
    forkMessage() {
      return sprintf(
        __(
          "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request.",
        ),
        {
          tag_start: '<span class="js-file-fork-suggestion-section-action">',
          tag_end: '</span>',
        },
        false,
      );
    },
86 87
  },
  watch: {
88
    isCollapsed: function fileCollapsedWatch(newVal, oldVal) {
89
      if (!newVal && oldVal && !this.hasDiff) {
90 91
        this.handleLoadCollapsedDiff();
      }
P
Phil Hughes 已提交
92 93 94

      this.setFileCollapsed({ filePath: this.file.file_path, collapsed: newVal });
    },
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    'file.file_hash': {
      handler: function watchFileHash() {
        if (
          this.glFeatures.autoExpandCollapsedDiffs &&
          this.viewDiffsFileByFile &&
          this.file.viewer.collapsed
        ) {
          this.isCollapsed = false;
          this.handleLoadCollapsedDiff();
        } else {
          this.isCollapsed = this.file.viewer.collapsed || false;
        }
      },
      immediate: true,
    },
P
Phil Hughes 已提交
110
    'file.viewer.collapsed': function setIsCollapsed(newVal) {
111 112 113
      if (!this.viewDiffsFileByFile && !this.glFeatures.autoExpandCollapsedDiffs) {
        this.isCollapsed = newVal;
      }
114
    },
F
Felipe Artur 已提交
115
  },
116 117 118
  created() {
    eventHub.$on(`loadCollapsedDiff/${this.file.file_hash}`, this.handleLoadCollapsedDiff);
  },
F
Felipe Artur 已提交
119
  methods: {
P
Phil Hughes 已提交
120 121 122 123 124 125
    ...mapActions('diffs', [
      'loadCollapsedDiff',
      'assignDiscussionsToDiff',
      'setRenderIt',
      'setFileCollapsed',
    ]),
F
Felipe Artur 已提交
126
    handleToggle() {
127
      if (!this.hasDiff) {
F
Felipe Artur 已提交
128 129
        this.handleLoadCollapsedDiff();
      } else {
130
        this.isCollapsed = !this.isCollapsed;
P
Phil Hughes 已提交
131
        this.setRenderIt(this.file);
F
Felipe Artur 已提交
132 133 134 135 136 137 138 139
      }
    },
    handleLoadCollapsedDiff() {
      this.isLoadingCollapsedDiff = true;

      this.loadCollapsedDiff(this.file)
        .then(() => {
          this.isLoadingCollapsedDiff = false;
140
          this.isCollapsed = false;
P
Phil Hughes 已提交
141
          this.setRenderIt(this.file);
F
Felipe Artur 已提交
142
        })
143 144 145
        .then(() => {
          requestIdleCallback(
            () => {
146
              this.assignDiscussionsToDiff(this.getDiffFileDiscussions(this.file));
147 148 149 150
            },
            { timeout: 1000 },
          );
        })
F
Felipe Artur 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
        .catch(() => {
          this.isLoadingCollapsedDiff = false;
          createFlash(__('Something went wrong on our end. Please try again!'));
        });
    },
    showForkMessage() {
      this.forkMessageVisible = true;
    },
    hideForkMessage() {
      this.forkMessageVisible = false;
    },
  },
};
</script>

<template>
  <div
P
Phil Hughes 已提交
168
    :id="file.file_hash"
169
    :class="{
170
      'is-active': currentDiffFileId === file.file_hash,
171
      'comments-disabled': Boolean(file.brokenSymlink),
172
    }"
173
    :data-path="file.new_path"
F
Felipe Artur 已提交
174 175 176
    class="diff-file file-holder"
  >
    <diff-file-header
177
      :can-current-user-fork="canCurrentUserFork"
F
Felipe Artur 已提交
178 179 180 181
      :diff-file="file"
      :collapsible="true"
      :expanded="!isCollapsed"
      :add-merge-request-buttons="true"
182
      :view-diffs-file-by-file="viewDiffsFileByFile"
F
Felipe Artur 已提交
183 184 185 186 187
      class="js-file-title file-title"
      @toggleFile="handleToggle"
      @showForkMessage="showForkMessage"
    />

M
Mike Greiling 已提交
188
    <div v-if="forkMessageVisible" class="js-file-fork-suggestion-section file-fork-suggestion">
A
André Luís 已提交
189
      <span class="file-fork-suggestion-note" v-html="forkMessage"></span>
F
Felipe Artur 已提交
190
      <a
P
Phil Hughes 已提交
191
        :href="file.fork_path"
F
Felipe Artur 已提交
192
        class="js-fork-suggestion-button btn btn-grouped btn-inverted btn-success"
193
        >{{ __('Fork') }}</a
F
Felipe Artur 已提交
194 195 196 197 198 199
      >
      <button
        class="js-cancel-fork-suggestion-button btn btn-grouped"
        type="button"
        @click="hideForkMessage"
      >
200
        {{ __('Cancel') }}
F
Felipe Artur 已提交
201 202
      </button>
    </div>
M
Mike Greiling 已提交
203
    <gl-loading-icon v-if="showLoadingIcon" class="diff-content loading" />
204
    <template v-else>
205 206 207 208
      <div :id="`diff-content-${file.file_hash}`">
        <div v-if="errorMessage" class="diff-viewer">
          <div class="nothing-here-block" v-html="errorMessage"></div>
        </div>
209 210 211 212 213 214 215 216 217 218 219 220 221
        <template v-else>
          <div v-show="isCollapsed" class="nothing-here-block diff-collapsed">
            {{ __('This diff is collapsed.') }}
            <a class="click-to-expand js-click-to-expand" href="#" @click.prevent="handleToggle">{{
              __('Click to expand it.')
            }}</a>
          </div>
          <diff-content
            v-show="!isCollapsed && !isFileTooLarge"
            :diff-file="file"
            :help-page-path="helpPagePath"
          />
        </template>
222 223
      </div>
    </template>
F
Felipe Artur 已提交
224 225
  </div>
</template>
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

<style>
@keyframes shadow-fade {
  from {
    box-shadow: 0 0 4px #919191;
  }

  to {
    box-shadow: 0 0 0 #dfdfdf;
  }
}

.diff-file.is-active {
  box-shadow: 0 0 0 #dfdfdf;
  animation: shadow-fade 1.2s 0.1s 1;
}
</style>