diff --git a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.html b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.html
index c593cdb992..3dbf5354c5 100644
--- a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.html
+++ b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.html
@@ -8,7 +8,7 @@
data-test-id="import-collection"
[popper]="'COLLECTIONS_IMPORT_TEXT' | translate"
[popperPlacement]="'bottom'"
- (click)="importCollectionChange.next()"
+ (click)="importCollectionsChange.next()"
>
diff --git a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.spec.ts b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.spec.ts
index 05af22eff4..a37b9fb064 100644
--- a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.spec.ts
+++ b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.spec.ts
@@ -189,7 +189,7 @@ describe('QueryCollectionsComponent', () => {
expect(wrapper.emitted('exportCollectionChange')).toBeTruthy();
});
- it('should emit "importCollectionChange" when clicking import collection button', async() => {
+ it('should emit "importCollectionsChange" when clicking import collection button', async() => {
wrapper.setProps({
showCollections: true,
collections: [
@@ -203,11 +203,11 @@ describe('QueryCollectionsComponent', () => {
await wrapper.nextTick();
- const importCollectionButton = wrapper.find('[data-test-id="import-collection"]');
+ const importCollectionsButton = wrapper.find('[data-test-id="import-collection"]');
- importCollectionButton.emit('click');
+ importCollectionsButton.emit('click');
- expect(wrapper.emitted('importCollectionChange')).toBeTruthy();
+ expect(wrapper.emitted('importCollectionsChange')).toBeTruthy();
});
it('should emit "sortCollectionsChange" when clicking one of the sort options', async() => {
diff --git a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.ts b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.ts
index 1a5bd78aaa..819d9734e0 100644
--- a/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.ts
+++ b/packages/altair-app/src/app/modules/altair/components/query-collections/query-collections.component.ts
@@ -17,7 +17,7 @@ export class QueryCollectionsComponent implements OnInit {
@Output() deleteCollectionChange: EventEmitter<{ collectionId: IQueryCollection['id'] }> = new EventEmitter();
@Output() editCollectionChange: EventEmitter<{ collection: IQueryCollection }> = new EventEmitter();
@Output() exportCollectionChange = new EventEmitter();
- @Output() importCollectionChange = new EventEmitter();
+ @Output() importCollectionsChange = new EventEmitter();
@Output() sortCollectionsChange = new EventEmitter();
constructor(
diff --git a/packages/altair-app/src/app/modules/altair/containers/app/app.component.html b/packages/altair-app/src/app/modules/altair/containers/app/app.component.html
index 9cb139ce95..9f028033cd 100644
--- a/packages/altair-app/src/app/modules/altair/containers/app/app.component.html
+++ b/packages/altair-app/src/app/modules/altair/containers/app/app.component.html
@@ -308,7 +308,7 @@
(deleteCollectionChange)="deleteCollection($event)"
(editCollectionChange)="toggleEditCollectionDialog($event)"
(exportCollectionChange)="exportCollection($event)"
- (importCollectionChange)="importCollection()"
+ (importCollectionsChange)="importCollections()"
(sortCollectionsChange)="sortCollections($event)"
>
diff --git a/packages/altair-app/src/app/modules/altair/containers/app/app.component.ts b/packages/altair-app/src/app/modules/altair/containers/app/app.component.ts
index c1e0befd7b..fd5dba2124 100644
--- a/packages/altair-app/src/app/modules/altair/containers/app/app.component.ts
+++ b/packages/altair-app/src/app/modules/altair/containers/app/app.component.ts
@@ -482,8 +482,8 @@ export class AppComponent {
this.store.dispatch(new collectionActions.ExportCollectionAction({ collectionId }));
}
- importCollection() {
- this.store.dispatch(new collectionActions.ImportCollectionAction());
+ importCollections() {
+ this.store.dispatch(new collectionActions.ImportCollectionsAction());
}
toggleEditCollectionDialog({ collection }: { collection: IQueryCollection }) {
diff --git a/packages/altair-app/src/app/modules/altair/effects/query-collection.effect.ts b/packages/altair-app/src/app/modules/altair/effects/query-collection.effect.ts
index 355f90d8a4..6b871bf6d9 100644
--- a/packages/altair-app/src/app/modules/altair/effects/query-collection.effect.ts
+++ b/packages/altair-app/src/app/modules/altair/effects/query-collection.effect.ts
@@ -1,7 +1,7 @@
-import { EMPTY, Observable, of, zip, forkJoin, from } from 'rxjs';
+import { EMPTY, Observable, of, zip, forkJoin, from, pipe } from 'rxjs';
-import { map, withLatestFrom, switchMap, tap, catchError } from 'rxjs/operators';
+import { map, withLatestFrom, switchMap, tap, catchError, filter } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Store, Action } from '@ngrx/store';
import { createEffect, Actions, ofType } from '@ngrx/effects';
@@ -10,7 +10,7 @@ import * as fromRoot from '../store';
import * as collectionActions from '../store/collection/collection.action';
import { QueryCollectionService, WindowService, NotifyService } from '../services';
-import { downloadJson, openFile } from '../utils';
+import { downloadJson, openFile, openFiles } from '../utils';
import { RootState } from 'altair-graphql-core/build/types/state/state.interfaces';
@@ -155,24 +155,34 @@ export class QueryCollectionEffects {
}, { dispatch: false });
- importCollection$: Observable = createEffect(() => {
- return this.actions$
- .pipe(
- ofType(collectionActions.IMPORT_COLLECTION),
- switchMap(() => {
- return from(openFile({ accept: '.agc' }));
- }),
- switchMap((data: string) => this.collectionService.importCollectionDataFromJson(data)),
- tap(() => this.notifyService.success('Successfully imported collection.')),
- map(() => new collectionActions.LoadCollectionsAction()),
- catchError((error) => {
- const errorMessage = error.message ? error.message : error.toString();
- this.notifyService.error(`Something went wrong importing collection. Error: ${errorMessage}`);
- return EMPTY;
- }),
- )
+
+ importCollections$: Observable = createEffect(() => {
+ return this.actions$.pipe(
+ ofType(collectionActions.IMPORT_COLLECTIONS),
+ switchMap(() => {
+ return from(openFiles({ accept: ".agc" }));
+ }),
+ pipe(filter((e) => e !== undefined)),
+ switchMap((data: string[]) =>
+ data.map((elem) =>
+ this.collectionService.importCollectionDataFromJson(elem)
+ )
+ ),
+ tap(() =>
+ this.notifyService.success("Successfully imported collection.")
+ ),
+ map(() => new collectionActions.LoadCollectionsAction()),
+ catchError((error) => {
+ const errorMessage = error.message ? error.message : error.toString();
+ this.notifyService.error(
+ `Something went wrong importing collection. Error: ${errorMessage}`
+ );
+ return EMPTY;
+ })
+ );
});
+
constructor(
private actions$: Actions,
private store: Store,
diff --git a/packages/altair-app/src/app/modules/altair/store/collection/collection.action.ts b/packages/altair-app/src/app/modules/altair/store/collection/collection.action.ts
index d44b493aec..8a46329721 100644
--- a/packages/altair-app/src/app/modules/altair/store/collection/collection.action.ts
+++ b/packages/altair-app/src/app/modules/altair/store/collection/collection.action.ts
@@ -12,7 +12,7 @@ export const LOAD_COLLECTIONS = 'LOAD_COLLECTIONS';
export const SET_ACTIVE_COLLECTION = 'SET_ACTIVE_COLLECTION';
export const UPDATE_COLLECTION = 'UPDATE_COLLECTION';
-export const IMPORT_COLLECTION = 'IMPORT_COLLECTION';
+export const IMPORT_COLLECTIONS = 'IMPORT_COLLECTIONS';
export const EXPORT_COLLECTION = 'EXPORT_COLLECTION';
export const SORT_COLLECTIONS = 'SORT_COLLECTIONS';
@@ -75,8 +75,8 @@ export class ExportCollectionAction implements NGRXAction {
constructor(public payload: { collectionId: number }) {}
}
-export class ImportCollectionAction implements NGRXAction {
- readonly type = IMPORT_COLLECTION;
+export class ImportCollectionsAction implements NGRXAction {
+ readonly type = IMPORT_COLLECTIONS;
}
export class SortCollectionsAction implements NGRXAction {
@@ -96,6 +96,6 @@ export type Action =
| UpdateCollectionAction
| LoadCollectionsAction
| ExportCollectionAction
- | ImportCollectionAction
+ | ImportCollectionsAction
| SortCollectionsAction
;
diff --git a/packages/altair-app/src/app/modules/altair/utils/index.ts b/packages/altair-app/src/app/modules/altair/utils/index.ts
index 9bb52c5d0a..42998f32c5 100644
--- a/packages/altair-app/src/app/modules/altair/utils/index.ts
+++ b/packages/altair-app/src/app/modules/altair/utils/index.ts
@@ -64,6 +64,24 @@ export const getFileStr = (files: FileList) => {
fileReader.readAsText(files[0]);
});
};
+
+export const getFilesStr = (files: FileList) => {
+ return Promise.all(
+ Array(files.length).map(
+ (_, index) =>
+ new Promise((resolve, reject) => {
+ const fileReader = new FileReader();
+ fileReader.onload = function (e: any) {
+ const contents: string = e.target.result;
+
+ // Resolve file content
+ resolve(contents);
+ };
+ fileReader.readAsText(files[index]);
+ })
+ )
+ );
+};
interface FileDialogOptions {
readonly multiple?: boolean;
readonly accept?: string|ReadonlyArray;
@@ -75,7 +93,15 @@ export const openFile = async (opts: FileDialogOptions = {}) => {
} catch (err) {
debug.log('There was an issue while opening the file: ', err);
}
-}
+};
+export const openFiles = async (opts: FileDialogOptions = {}) => {
+ try {
+ const files = await fileDialog({ ...opts, multiple: true });
+ return getFilesStr(files);
+ } catch (err) {
+ debug.log('There was an issue while opening the files: ', err);
+ }
+};
export const isExtension = !!((window as any).chrome && (window as any).chrome.runtime && (window as any).chrome.runtime.id);
export const isFirefoxExtension = !!((window as any).chrome && (window as any).chrome.geckoProfiler);