summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
blob: 7caa37d9ad4819134bc8e26e555889fe9ac5742f (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
import { debounce, merge } from 'lodash';

export const KEY = 'gl-bulk-imports-import-state';
export const DEBOUNCE_INTERVAL = 200;

export class SourceGroupsManager {
  constructor({ sourceUrl, storage = window.localStorage }) {
    this.sourceUrl = sourceUrl;

    this.storage = storage;
    this.importStates = this.loadImportStatesFromStorage();
  }

  loadImportStatesFromStorage() {
    try {
      return Object.fromEntries(
        Object.entries(JSON.parse(this.storage.getItem(KEY)) ?? {}).map(([jobId, config]) => {
          // new format of storage
          if (config.groups) {
            return [jobId, config];
          }

          return [
            jobId,
            {
              status: config.status,
              groups: [{ id: config.id, importTarget: config.importTarget }],
            },
          ];
        }),
      );
    } catch {
      return {};
    }
  }

  createImportState(importId, jobConfig) {
    this.importStates[importId] = {
      status: jobConfig.status,
      groups: jobConfig.groups.map((g) => ({
        importTarget: { ...g.import_target },
        id: g.id,
      })),
    };
    this.saveImportStatesToStorage();
  }

  updateImportProgress(importId, status) {
    const currentState = this.importStates[importId];
    if (!currentState) {
      return;
    }

    currentState.status = status;
    this.saveImportStatesToStorage();
  }

  getImportedGroupsByJobId(jobId) {
    return this.importStates[jobId]?.groups ?? [];
  }

  getImportStateFromStorageByGroupId(groupId) {
    const [jobId, importState] =
      Object.entries(this.importStates)
        .reverse()
        .find(([, state]) => state.groups.some((g) => g.id === groupId)) ?? [];

    if (!jobId) {
      return null;
    }

    const group = importState.groups.find((g) => g.id === groupId);
    return { jobId, importState: { ...group, status: importState.status } };
  }

  saveImportStatesToStorage = debounce(() => {
    try {
      // storage might be changed in other tab so fetch first
      this.storage.setItem(
        KEY,
        JSON.stringify(merge({}, this.loadImportStatesFromStorage(), this.importStates)),
      );
    } catch {
      // empty catch intentional: storage might be unavailable or full
    }
  }, DEBOUNCE_INTERVAL);
}