mr_widget_store.js 6.7 KB
Newer Older
F
Fatih Acet 已提交
1 2
import Timeago from 'timeago.js';
import { getStateKey } from '../dependencies';
3
import { stateKey } from './state_maps';
4
import { formatDate } from '../../lib/utils/datetime_utility';
F
Fatih Acet 已提交
5 6 7

export default class MergeRequestStore {
  constructor(data) {
8
    this.sha = data.diff_head_sha;
9
    this.gitlabLogo = data.gitlabLogo;
10

F
Fatih Acet 已提交
11 12 13 14 15 16 17
    this.setData(data);
  }

  setData(data) {
    const currentUser = data.current_user;
    const pipelineStatus = data.pipeline ? data.pipeline.details.status : null;

18 19 20 21 22
    this.squash = data.squash;
    this.squashBeforeMergeHelpPath = this.squashBeforeMergeHelpPath ||
      data.squash_before_merge_help_path;
    this.enableSquashBeforeMerge = this.enableSquashBeforeMerge || true;

F
Fatih Acet 已提交
23 24 25 26 27
    this.title = data.title;
    this.targetBranch = data.target_branch;
    this.sourceBranch = data.source_branch;
    this.mergeStatus = data.merge_status;
    this.commitMessage = data.merge_commit_message;
28
    this.shortMergeCommitSha = data.short_merge_commit_sha;
F
Fatih Acet 已提交
29 30 31 32 33
    this.commitMessageWithDescription = data.merge_commit_message_with_description;
    this.commitsCount = data.commits_count;
    this.divergedCommitsCount = data.diverged_commits_count;
    this.pipeline = data.pipeline || {};
    this.deployments = this.deployments || data.deployments || [];
34
    this.initRebase(data);
F
Fatih Acet 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47

    if (data.issues_links) {
      const links = data.issues_links;
      const { closing } = links;
      const mentioned = links.mentioned_but_not_closing;
      const assignToMe = links.assign_to_closing;

      if (closing || mentioned || assignToMe) {
        this.relatedLinks = { closing, mentioned, assignToMe };
      }
    }

    this.updatedAt = data.updated_at;
48 49
    this.metrics = MergeRequestStore.buildMetrics(data.metrics);
    this.setToMWPSBy = MergeRequestStore.formatUserObject(data.merge_user || {});
F
Fatih Acet 已提交
50 51 52 53 54
    this.mergeUserId = data.merge_user_id;
    this.currentUserId = gon.current_user_id;
    this.sourceBranchPath = data.source_branch_path;
    this.sourceBranchLink = data.source_branch_with_namespace_link;
    this.mergeError = data.merge_error;
55 56
    this.targetBranchPath = data.target_branch_commits_path;
    this.targetBranchTreePath = data.target_branch_tree_path;
F
Fatih Acet 已提交
57 58 59 60
    this.conflictResolutionPath = data.conflict_resolution_path;
    this.cancelAutoMergePath = data.cancel_merge_when_pipeline_succeeds_path;
    this.removeWIPPath = data.remove_wip_path;
    this.sourceBranchRemoved = !data.source_branch_exists;
61
    this.shouldRemoveSourceBranch = data.remove_source_branch || false;
F
Fatih Acet 已提交
62 63 64
    this.onlyAllowMergeIfPipelineSucceeds = data.only_allow_merge_if_pipeline_succeeds || false;
    this.mergeWhenPipelineSucceeds = data.merge_when_pipeline_succeeds || false;
    this.mergePath = data.merge_path;
65
    this.ffOnlyEnabled = data.ff_only_enabled;
66
    this.shouldBeRebased = !!data.should_be_rebased;
F
Fatih Acet 已提交
67 68 69
    this.statusPath = data.status_path;
    this.emailPatchesPath = data.email_patches_path;
    this.plainDiffPath = data.plain_diff_path;
70
    this.newBlobPath = data.new_blob_path;
F
Fatih Acet 已提交
71 72 73
    this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path;
    this.mergeCheckPath = data.merge_check_path;
    this.mergeActionsContentPath = data.commit_change_content_path;
74
    this.mergeCommitPath = data.merge_commit_path;
F
Fatih Acet 已提交
75
    this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
76
    this.isOpen = data.state === 'opened';
F
Fatih Acet 已提交
77 78 79 80 81
    this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
    this.canRemoveSourceBranch = currentUser.can_remove_source_branch || false;
    this.canMerge = !!data.merge_path;
    this.canCreateIssue = currentUser.can_create_issue || false;
    this.canCancelAutomaticMerge = !!data.cancel_merge_when_pipeline_succeeds_path;
82
    this.hasSHAChanged = this.sha !== data.diff_head_sha;
F
Fatih Acet 已提交
83
    this.canBeMerged = data.can_be_merged || false;
84
    this.isMergeAllowed = data.mergeable || false;
85
    this.mergeOngoing = data.merge_ongoing;
86
    this.allowCollaboration = data.allow_collaboration;
F
Fatih Acet 已提交
87 88 89 90 91 92 93 94 95 96 97

    // Cherry-pick and Revert actions related
    this.canCherryPickInCurrentMR = currentUser.can_cherry_pick_on_current_merge_request || false;
    this.canRevertInCurrentMR = currentUser.can_revert_on_current_merge_request || false;
    this.cherryPickInForkPath = currentUser.cherry_pick_in_fork_path;
    this.revertInForkPath = currentUser.revert_in_fork_path;

    // CI related
    this.ciEnvironmentsStatusPath = data.ci_environments_status_path;
    this.hasCI = data.has_ci;
    this.ciStatus = data.ci_status;
98 99 100
    this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
    this.isPipelinePassing = this.ciStatus === 'success' || this.ciStatus === 'success_with_warnings';
    this.isPipelineSkipped = this.ciStatus === 'skipped';
F
Fatih Acet 已提交
101 102 103 104 105 106 107 108 109
    this.pipelineDetailedStatus = pipelineStatus;
    this.isPipelineActive = data.pipeline ? data.pipeline.active : false;
    this.isPipelineBlocked = pipelineStatus ? pipelineStatus.group === 'manual' : false;
    this.ciStatusFaviconPath = pipelineStatus ? pipelineStatus.favicon : null;

    this.setState(data);
  }

  setState(data) {
110 111 112 113 114
    if (this.mergeOngoing) {
      this.state = 'merging';
      return;
    }

F
Fatih Acet 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    if (this.isOpen) {
      this.state = getStateKey.call(this, data);
    } else {
      switch (data.state) {
        case 'merged':
          this.state = 'merged';
          break;
        case 'closed':
          this.state = 'closed';
          break;
        default:
          this.state = null;
      }
    }
  }

131 132 133 134
  get isNothingToMergeState() {
    return this.state === stateKey.nothingToMerge;
  }

135 136 137 138
  get isMergedState() {
    return this.state === stateKey.merged;
  }

139 140 141 142 143 144 145
  initRebase(data) {
    this.canPushToSourceBranch = data.can_push_to_source_branch;
    this.rebaseInProgress = data.rebase_in_progress;
    this.approvalsLeft = !data.approved;
    this.rebasePath = data.rebase_path;
  }

146
  static buildMetrics(metrics) {
147 148 149 150
    if (!metrics) {
      return {};
    }

151
    return {
152 153 154 155 156 157
      mergedBy: MergeRequestStore.formatUserObject(metrics.merged_by),
      closedBy: MergeRequestStore.formatUserObject(metrics.closed_by),
      mergedAt: formatDate(metrics.merged_at),
      closedAt: formatDate(metrics.closed_at),
      readableMergedAt: MergeRequestStore.getReadableDate(metrics.merged_at),
      readableClosedAt: MergeRequestStore.getReadableDate(metrics.closed_at),
158 159 160
    };
  }

161 162
  static formatUserObject(user) {
    if (!user) {
F
Fatih Acet 已提交
163 164 165 166
      return {};
    }

    return {
167 168 169 170
      name: user.name || '',
      username: user.username || '',
      webUrl: user.web_url || '',
      avatarUrl: user.avatar_url || '',
F
Fatih Acet 已提交
171 172 173
    };
  }

174 175
  static getReadableDate(date) {
    if (!date) {
176 177 178
      return '';
    }

F
Fatih Acet 已提交
179 180
    const timeagoInstance = new Timeago();

181
    return timeagoInstance.format(date);
F
Fatih Acet 已提交
182 183
  }
}