All files / app/assets/javascripts/repository log_tree.js

95% Statements 38/40
84.61% Branches 22/26
100% Functions 7/7
94.59% Lines 35/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95                1x 1x           18x       10x   9x 9x         10x 3x     10x   9x     10x   10x   10x 2x 2x     8x 8x 7x   1x       8x   7x 7x   7x                   7x 7x 7x 7x   7x         8x   7x   7x       7x 7x 7x       7x    
import produce from 'immer';
import { normalizeData } from 'ee_else_ce/repository/utils/commit';
import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import commitsQuery from './queries/commits.query.graphql';
import projectPathQuery from './queries/project_path.query.graphql';
import refQuery from './queries/ref.query.graphql';
 
const fetchpromises = {};
const resolvers = {};
let maxOffset;
let nextOffset;
let currentPath;
 
function setNextOffset(offset) {
  nextOffset = offset || null;
}
 
export function resolveCommit(commits, path, { resolve, entry }) {
  const commit = commits.find((c) => c.filePath === joinPaths(path, entry.name));
 
  Eif (commit) {
    resolve(commit);
  }
}
 
export function fetchLogsTree(client, path, offset, resolver = null, _maxOffset = null) {
  if (_maxOffset) {
    maxOffset = _maxOffset;
  }
 
  if (!currentPath || currentPath !== path) {
    // ensures the nextOffset is reset if the user changed directories
    setNextOffset(null);
  }
 
  currentPath = path;
 
  const offsetNumber = Number(offset);
 
  if (!nextOffset && offsetNumber > maxOffset) {
    setNextOffset(offsetNumber - 25); // ensures commit data is fetched for newly added rows that need data from the previous request (requests are made in batches of 25).
    return Promise.resolve();
  }
 
  Eif (resolver) {
    if (!resolvers[path]) {
      resolvers[path] = [resolver];
    } else {
      resolvers[path].push(resolver);
    }
  }
 
  if (fetchpromises[path]) return fetchpromises[path];
 
  const { projectPath } = client.readQuery({ query: projectPathQuery });
  const { escapedRef } = client.readQuery({ query: refQuery });
 
  fetchpromises[path] = axios
    .get(
      `${gon.relative_url_root}/${projectPath}/-/refs/${escapedRef}/logs_tree/${encodeURIComponent(
        path.replace(/^\//, ''),
      )}`,
      {
        params: { format: 'json', offset: nextOffset || offset },
      },
    )
    .then(({ data: newData, headers }) => {
      const headerLogsOffset = headers['more-logs-offset'];
      const sourceData = client.readQuery({ query: commitsQuery });
      const data = produce(sourceData, (draftState) => {
        draftState.commits.push(...normalizeData(newData, path));
      });
      client.writeQuery({
        query: commitsQuery,
        data,
      });
 
      resolvers[path].forEach((r) => resolveCommit(data.commits, path, r));
 
      delete fetchpromises[path];
 
      Iif (headerLogsOffset) {
        setNextOffset(null);
        fetchLogsTree(client, path, headerLogsOffset);
      } else {
        delete resolvers[path];
        maxOffset = null;
        setNextOffset(null);
      }
    });
 
  return fetchpromises[path];
}