Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups/graphql/services')
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js74
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js87
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js35
3 files changed, 74 insertions, 122 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js
new file mode 100644
index 00000000000..09bc7b33692
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/local_storage_cache.js
@@ -0,0 +1,74 @@
+import { debounce, merge } from 'lodash';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+
+const OLD_KEY = 'gl-bulk-imports-import-state';
+export const KEY = 'gl-bulk-imports-import-state-v2';
+export const DEBOUNCE_INTERVAL = DEFAULT_DEBOUNCE_AND_THROTTLE_MS;
+
+export class LocalStorageCache {
+ constructor({ storage = window.localStorage } = {}) {
+ this.storage = storage;
+ this.cache = this.loadCacheFromStorage();
+ try {
+ // remove old storage data
+ this.storage.removeItem(OLD_KEY);
+ } catch {
+ // empty catch intended
+ }
+
+ // cache for searching data by jobid
+ this.jobsLookupCache = {};
+ }
+
+ loadCacheFromStorage() {
+ try {
+ return JSON.parse(this.storage.getItem(KEY)) ?? {};
+ } catch {
+ return {};
+ }
+ }
+
+ set(webUrl, data) {
+ this.cache[webUrl] = data;
+ this.saveCacheToStorage();
+ // There are changes to jobIds, drop cache
+ this.jobsLookupCache = {};
+ }
+
+ get(webUrl) {
+ return this.cache[webUrl];
+ }
+
+ getCacheKeysByJobId(jobId) {
+ // this is invoked by polling, so we would like to cache results
+ if (!this.jobsLookupCache[jobId]) {
+ this.jobsLookupCache[jobId] = Object.keys(this.cache).filter(
+ (url) => this.cache[url]?.progress.id === jobId,
+ );
+ }
+
+ return this.jobsLookupCache[jobId];
+ }
+
+ updateStatusByJobId(jobId, status) {
+ this.getCacheKeysByJobId(jobId).forEach((webUrl) =>
+ this.set(webUrl, {
+ ...(this.get(webUrl) ?? {}),
+ progress: {
+ id: jobId,
+ status,
+ },
+ }),
+ );
+ this.saveCacheToStorage();
+ }
+
+ saveCacheToStorage = debounce(() => {
+ try {
+ // storage might be changed in other tab so fetch first
+ this.storage.setItem(KEY, JSON.stringify(merge({}, this.loadCacheFromStorage(), this.cache)));
+ } catch {
+ // empty catch intentional: storage might be unavailable or full
+ }
+ }, DEBOUNCE_INTERVAL);
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
deleted file mode 100644
index 7caa37d9ad4..00000000000
--- a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
+++ /dev/null
@@ -1,87 +0,0 @@
-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);
-}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
deleted file mode 100644
index 0297b3d3428..00000000000
--- a/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Visibility from 'visibilityjs';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import Poll from '~/lib/utils/poll';
-import { s__ } from '~/locale';
-
-export class StatusPoller {
- constructor({ updateImportStatus, pollPath }) {
- this.eTagPoll = new Poll({
- resource: {
- fetchJobs: () => axios.get(pollPath),
- },
- method: 'fetchJobs',
- successCallback: ({ data: statuses }) => {
- statuses.forEach((status) => updateImportStatus(status));
- },
- errorCallback: () =>
- createFlash({
- message: s__('BulkImport|Update of import statuses with realtime changes failed'),
- }),
- });
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- this.eTagPoll.restart();
- } else {
- this.eTagPoll.stop();
- }
- });
- }
-
- startPolling() {
- this.eTagPoll.makeRequest();
- }
-}