summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/work_items/notes/collapse_utils.js
blob: db7b4530e2ab0e3df3693fdc33b82550e2bc5a67 (plain)
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
import { DESCRIPTION_TYPE, TIME_DIFFERENCE_VALUE } from '~/notes/constants';

/**
 * Checks the time difference between two notes from their 'created_at' dates
 * returns an integer
 */
export const getTimeDifferenceInMinutes = (noteBeginning, noteEnd) => {
  const descriptionNoteBegin = new Date(noteBeginning.createdAt);
  const descriptionNoteEnd = new Date(noteEnd.createdAt);
  const timeDifferenceMinutes = (descriptionNoteEnd - descriptionNoteBegin) / 1000 / 60;

  return Math.ceil(timeDifferenceMinutes);
};

/**
 * Checks if a note is a system note and if the content is description
 *
 * @param {Object} note
 * @returns {Boolean}
 */
export const isDescriptionSystemNote = (note) => {
  return note.system && note.body === DESCRIPTION_TYPE;
};

/**
 * Collapses the system notes of a description type, e.g. Changed the description, n minutes ago
 * the notes will collapse as long as they happen no more than 10 minutes away from each away
 * in between the notes can be anything, another type of system note
 * (such as 'changed the weight') or a comment.
 *
 * @param {Array} notes
 * @returns {Array}
 */
export const collapseSystemNotes = (notes) => {
  let lastDescriptionSystemNote = null;
  let lastDescriptionSystemNoteIndex = -1;

  return notes.reduce((acc, currentNote) => {
    const note = currentNote.notes.nodes[0];
    let lastStartVersionId = '';

    if (isDescriptionSystemNote(note)) {
      // is it the first one?
      if (!lastDescriptionSystemNote) {
        lastDescriptionSystemNote = note;
      } else {
        const timeDifferenceMinutes = getTimeDifferenceInMinutes(lastDescriptionSystemNote, note);

        // are they less than 10 minutes apart from the same user?
        if (
          timeDifferenceMinutes > TIME_DIFFERENCE_VALUE ||
          note.author.id !== lastDescriptionSystemNote.author.id ||
          lastDescriptionSystemNote.systemNoteMetadata.descriptionVersion?.deleted
        ) {
          // update the previous system note
          lastDescriptionSystemNote = note;
        } else {
          // set the first version to fetch grouped system note versions

          lastStartVersionId = lastDescriptionSystemNote.systemNoteMetadata.descriptionVersion.id;

          // delete the previous one
          acc.splice(lastDescriptionSystemNoteIndex, 1);
        }
      }

      // update the previous system note index
      lastDescriptionSystemNoteIndex = acc.length;

      acc.push({
        notes: {
          nodes: [
            {
              ...note,
              systemNoteMetadata: {
                ...note.systemNoteMetadata,
                descriptionVersion: {
                  ...note.systemNoteMetadata.descriptionVersion,
                  startVersionId: lastStartVersionId,
                },
              },
            },
          ],
        },
      });
    } else {
      acc.push(currentNote);
    }

    return acc;
  }, []);
};