diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fd60918d046a178b951afd91aed075d9066e957..7e4f5fb605bf195de844d3c2ef21af7d6caddec7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.6.0] - 2021-xx
+### Added
+- #135 => Save search result page state when navigate to detail page
+
### Changed
- #155 => Display dataset label instead of dataset name in result page
diff --git a/src/app/search-multiple/components/result/datasets-result.component.html b/src/app/search-multiple/components/result/datasets-result.component.html
index f9d68bf2cf67b7b18e222524c65a7315a2ae55ae..cfa0e0fe80b886448e403f4de8e71d6d6de591bd 100644
--- a/src/app/search-multiple/components/result/datasets-result.component.html
+++ b/src/app/search-multiple/components/result/datasets-result.component.html
@@ -1,7 +1,11 @@
-
+
{{ dataset.label }}
diff --git a/src/app/search-multiple/components/result/datasets-result.component.spec.ts b/src/app/search-multiple/components/result/datasets-result.component.spec.ts
index 965b62d1d6f3ed6afab356a8251740f52e45fb29..48c91004a6c721178bfacafa932b6e8077409b7f 100644
--- a/src/app/search-multiple/components/result/datasets-result.component.spec.ts
+++ b/src/app/search-multiple/components/result/datasets-result.component.spec.ts
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DatasetsResultComponent } from './datasets-result.component';
import { Attribute, Dataset } from '../../../metamodel/model';
-import { Pagination, PaginationOrder } from '../../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../../shared/datatable/store/model';
import { ATTRIBUTE_LIST, DATASET_FAMILY_LIST, DATASET_LIST } from '../../../../settings/test-data';
describe('[SearchMultiple][Result] Component: DatasetsResultComponent', () => {
diff --git a/src/app/search-multiple/components/result/datasets-result.component.ts b/src/app/search-multiple/components/result/datasets-result.component.ts
index e913ee0f87b940e3b7cb52556df30813cfdc4961..6fa34579a1cd9da5579285674ab7956d97d945ff 100644
--- a/src/app/search-multiple/components/result/datasets-result.component.ts
+++ b/src/app/search-multiple/components/result/datasets-result.component.ts
@@ -13,7 +13,7 @@ import { Dictionary } from '@ngrx/entity';
import { DataByDataset, DatasetCount } from '../../store/model';
import { Attribute, AttributesByDataset, Dataset, Family } from '../../../metamodel/model';
-import { Pagination, PaginationOrder } from '../../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../../shared/datatable/store/model';
import { ConeSearch } from '../../../shared/cone-search/store/model';
import { sortByDisplay } from '../../../shared/utils';
@@ -37,9 +37,11 @@ export class DatasetsResultComponent {
@Input() allAttributeList: Dictionary;
@Input() datasetsWithData: (string | number) [];
@Input() allData: Dictionary;
+ @Input() datatableState: { dname: string, accordionIsOpen: boolean }[];
@Input() selectedData: { dname: string, data: (string | number)[] }[];
@Output() retrieveMeta: EventEmitter = new EventEmitter();
@Output() retrieveData: EventEmitter = new EventEmitter();
+ @Output() updateDatatableState: EventEmitter<{ dname: string, accordionIsOpen: boolean }[]> = new EventEmitter();
@Output() updateSelectedData: EventEmitter<{ dname: string, data: (string | number)[] }[]> = new EventEmitter();
/**
@@ -183,12 +185,32 @@ export class DatasetsResultComponent {
this.updateSelectedData.emit(updatedSelection);
}
+ /**
+ * When accordion state change, emits update datables state and calls loadData function.
+ *
+ * @param {boolean} isOpen - The accordion state.
+ * @param {string} dname - The dataset name.
+ */
+ changeAccordionState(isOpen: boolean, dname: string) : void {
+ let updatedDatatableState: { dname: string, accordionIsOpen: boolean }[];
+ const datatableStatus: { dname: string, accordionIsOpen: boolean } = { dname: dname, accordionIsOpen: isOpen };
+ const index: number = this.datatableState.findIndex(ds => ds.dname === dname);
+ if (index === -1) {
+ updatedDatatableState = [...this.datatableState, datatableStatus];
+ } else {
+ updatedDatatableState = this.datatableState.filter(ds => ds.dname !== dname);
+ updatedDatatableState.push(datatableStatus);
+ }
+ this.updateDatatableState.emit(updatedDatatableState);
+ this.loadData(isOpen, dname);
+ }
+
/**
* When accordion opens, emits retrieve metadata for the
* given dataset name if not already loaded and emits retrieve
* data for the given dataset name otherwise.
*
- * @param {boolean} isOpen - If the accordion is open.
+ * @param {boolean} isOpen - The accordion state.
* @param {string} dname - The dataset name.
*/
loadData(isOpen: boolean, dname: string) : void {
diff --git a/src/app/search-multiple/containers/result-multiple.component.html b/src/app/search-multiple/containers/result-multiple.component.html
index d9a7fc4181952b6ad62148d44dbcf15f2456d717..8153dc0470e8f42e557aa107aed15b6fd0b1b152 100644
--- a/src/app/search-multiple/containers/result-multiple.component.html
+++ b/src/app/search-multiple/containers/result-multiple.component.html
@@ -22,9 +22,11 @@
[allAttributeList]="allAttributeList | async"
[datasetsWithData]="datasetsWithData | async"
[allData]="allData | async"
+ [datatableState]="datatableState | async"
[selectedData]="selectedData | async"
(retrieveMeta)="retrieveMeta($event)"
(retrieveData)="retrieveData($event)"
+ (updateDatatableState)="updateDatatableState($event)"
(updateSelectedData)="updateSelectedData($event)">
diff --git a/src/app/search-multiple/containers/result-multiple.component.spec.ts b/src/app/search-multiple/containers/result-multiple.component.spec.ts
index 34263ec5b34c2ca75f5b3428ffa7d28108f6884c..872a73df3e750744eab58b774fa4bc501860ed59 100644
--- a/src/app/search-multiple/containers/result-multiple.component.spec.ts
+++ b/src/app/search-multiple/containers/result-multiple.component.spec.ts
@@ -15,7 +15,7 @@ import { AttributesByDataset, Dataset, Family } from '../../metamodel/model';
import * as fromConeSearch from '../../shared/cone-search/store/cone-search.reducer';
import { ConeSearch } from '../../shared/cone-search/store/model';
import { ScrollTopService } from '../../shared/service/sroll-top.service';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
import { RouterLinkDirectiveStub } from '../../../settings/test-data/router-link-directive-stub';
describe('[SearchMultiple] Container: ResultMultipleComponent', () => {
diff --git a/src/app/search-multiple/containers/result-multiple.component.ts b/src/app/search-multiple/containers/result-multiple.component.ts
index 64b5ed34853a6e95a67995bcd8ff36b808ccc136..f72ddd42cc745927e5718cdb00ccfeaa0df2aafd 100644
--- a/src/app/search-multiple/containers/result-multiple.component.ts
+++ b/src/app/search-multiple/containers/result-multiple.component.ts
@@ -24,7 +24,7 @@ import * as metamodelSelector from '../../metamodel/selectors';
import { AttributesByDataset, Dataset, Family } from '../../metamodel/model';
import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
import { ConeSearch } from '../../shared/cone-search/store/model';
-import { Pagination } from '../../shared/datatable/model';
+import { Pagination } from '../../shared/datatable/store/model';
import { ScrollTopService } from '../../shared/service/sroll-top.service';
/**
@@ -65,6 +65,7 @@ export class ResultMultipleComponent implements OnInit, OnDestroy {
public data: Observable<{ dname: string, data: any[]}[]>;
public datasetsWithData: Observable;
public allData: Observable>;
+ public datatableState: Observable<{ dname: string, accordionIsOpen: boolean }[]>;
public selectedData: Observable<{ dname: string, data: (number | string)[] }[]>;
constructor(private store: Store, private scrollTopService: ScrollTopService) {
@@ -83,6 +84,7 @@ export class ResultMultipleComponent implements OnInit, OnDestroy {
this.allAttributeList = this.store.select(metamodelSelector.getAllAttributeList);
this.datasetsWithData = this.store.select(searchMultipleSelector.getDatasetsWithData);
this.allData = this.store.select(searchMultipleSelector.getAllData);
+ this.datatableState = store.select(searchMultipleSelector.getDatatableState);
this.selectedData = this.store.select(searchMultipleSelector.getSelectedData);
}
@@ -120,6 +122,15 @@ export class ResultMultipleComponent implements OnInit, OnDestroy {
this.store.dispatch(new searchMultipleActions.RetrieveDataAction(params));
}
+ /**
+ * Dispatches action to update datatables state with the given updated datatables state.
+ *
+ * @param {{ dname: string, accordionIsOpen: boolean }[]} updatedDatatableState - The updated datatables state.
+ */
+ updateDatatableState(updatedDatatableState: { dname: string, accordionIsOpen: boolean }[]): void {
+ this.store.dispatch(new searchMultipleActions.UpdateDatatableStateAction(updatedDatatableState));
+ }
+
/**
* Dispatches action to update data selection with the given updated selected data.
*
diff --git a/src/app/search-multiple/containers/search-multiple.component.ts b/src/app/search-multiple/containers/search-multiple.component.ts
index 99605bc61a9f75ea72fb70b5ec77d5cc0917d0fa..5ce7ea6a4c89b3311ddb50ab1cb631ba17394e23 100644
--- a/src/app/search-multiple/containers/search-multiple.component.ts
+++ b/src/app/search-multiple/containers/search-multiple.component.ts
@@ -18,6 +18,7 @@ import { SearchMultipleQueryParams } from '../store/model';
import * as searchActions from '../../search/store/search.action';
import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
import * as coneSearchActions from '../../shared/cone-search/store/cone-search.action';
+import * as datatableActions from '../../shared/datatable/store/datatable.action';
@Component({
selector: 'app-search-multiple',
@@ -46,5 +47,6 @@ export class SearchMultipleComponent {
this.queryParams = store.select(searchMultipleSelector.getQueryParams);
this.store.dispatch(new searchActions.ResetSearchAction());
this.store.dispatch(new coneSearchActions.DeleteConeSearchAction());
+ this.store.dispatch(new datatableActions.ResetDatatableAction());
}
}
diff --git a/src/app/search-multiple/store/search-multiple.action.spec.ts b/src/app/search-multiple/store/search-multiple.action.spec.ts
index 9a89055158e2178634e6081bbf95710c3a27ab4b..c5400dbaae8c9bb9b547f4236dc6f76794b6573c 100644
--- a/src/app/search-multiple/store/search-multiple.action.spec.ts
+++ b/src/app/search-multiple/store/search-multiple.action.spec.ts
@@ -1,6 +1,6 @@
import * as searchMultipleActions from '../store/search-multiple.action';
import { DatasetCount } from './model';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
describe('[SearchMultiple] Action', () => {
it('should create InitSearchByUrlAction', () => {
@@ -77,6 +77,12 @@ describe('[SearchMultiple] Action', () => {
expect(action.payload).toEqual('toto');
});
+ it('should create UpdateDatatableStateAction', () => {
+ const action = new searchMultipleActions.UpdateDatatableStateAction([{ dname: 'toto', accordionIsOpen: false }]);
+ expect(action.type).toEqual(searchMultipleActions.UPDATE_DATATABLE_STATE);
+ expect(action.payload).toEqual([{ dname: 'toto', accordionIsOpen: false }]);
+ });
+
it('should create UpdateSelectedDataAction', () => {
const action = new searchMultipleActions.UpdateSelectedDataAction([{ dname: 'toto', data: [1] }]);
expect(action.type).toEqual(searchMultipleActions.UPDATE_SELECTED_DATA);
diff --git a/src/app/search-multiple/store/search-multiple.action.ts b/src/app/search-multiple/store/search-multiple.action.ts
index c97e8045dc7fada826dab8d5c76642a4fb2d0b3a..b4d1734519737b5452bbf7cc1e34ff08ac572177 100644
--- a/src/app/search-multiple/store/search-multiple.action.ts
+++ b/src/app/search-multiple/store/search-multiple.action.ts
@@ -10,7 +10,7 @@
import { Action } from '@ngrx/store';
import { DatasetCount } from './model';
-import { Pagination } from '../../shared/datatable/model';
+import { Pagination } from '../../shared/datatable/store/model';
export const INIT_SEARCH_BY_URL = '[SearchMultiple] Init By Url';
@@ -26,6 +26,7 @@ export const RETRIEVE_DATASETS_COUNT_FAIL = '[SearchMultiple] Retrieve Datasets
export const RETRIEVE_DATA = '[SearchMultiple] Retrieve Data';
export const RETRIEVE_DATA_SUCCESS = '[SearchMultiple] Retrieve Data Success';
export const RETRIEVE_DATA_FAIL = '[SearchMultiple] Retrieve Data Fail';
+export const UPDATE_DATATABLE_STATE = '[SearchMultiple] Update Datatable State';
export const UPDATE_SELECTED_DATA = '[SearchMultiple] Update Selected Data';
export const DESTROY_RESULTS = '[SearchMultiple] Destroy Results';
export const RESET_SEARCH = '[SearchMultiple] Reset Search';
@@ -173,6 +174,17 @@ export class RetrieveDataFailAction implements Action {
constructor(public payload: string) { }
}
+/**
+ * @class
+ * @classdesc UpdateDatatableStateAction action.
+ * @readonly
+ */
+export class UpdateDatatableStateAction implements Action {
+ readonly type = UPDATE_DATATABLE_STATE;
+
+ constructor(public payload: { dname: string, accordionIsOpen: boolean }[]) { }
+}
+
/**
* @class
* @classdesc UpdateSelectedDataAction action.
@@ -220,6 +232,7 @@ export type Actions
| RetrieveDataAction
| RetrieveDataSuccessAction
| RetrieveDataFailAction
+ | UpdateDatatableStateAction
| UpdateSelectedDataAction
| DestroyResultsAction
| ResetSearchAction;
diff --git a/src/app/search-multiple/store/search-multiple.effects.ts b/src/app/search-multiple/store/search-multiple.effects.ts
index 6ff23ceffacade44bd860a9d497a68d601bb1dfe..89f9198f2bbaeac9ae071513d0955ba2cb18cf64 100644
--- a/src/app/search-multiple/store/search-multiple.effects.ts
+++ b/src/app/search-multiple/store/search-multiple.effects.ts
@@ -26,7 +26,7 @@ import { Dataset } from '../../metamodel/model';
import * as fromConeSearch from '../../shared/cone-search/store/cone-search.reducer';
import * as coneSearchActions from '../../shared/cone-search/store/cone-search.action';
import { ConeSearch } from '../../shared/cone-search/store/model';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
import * as utils from '../../shared/utils';
@Injectable()
diff --git a/src/app/search-multiple/store/search-multiple.reducer.spec.ts b/src/app/search-multiple/store/search-multiple.reducer.spec.ts
index b06696224f56e611580a22da090fda6a4d2c4c76..d17dfc9b742fb42b96aa3c2969aeb757daef12a3 100644
--- a/src/app/search-multiple/store/search-multiple.reducer.spec.ts
+++ b/src/app/search-multiple/store/search-multiple.reducer.spec.ts
@@ -1,7 +1,7 @@
import * as fromSearchMultiple from './search-multiple.reducer';
import * as searchMultipleActions from './search-multiple.action';
import { DataByDataset, DatasetCount } from './model';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
describe('[SearchMultiple] Reducer', () => {
it('should return init state', () => {
@@ -30,6 +30,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -50,6 +51,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -70,6 +72,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -90,6 +93,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -110,6 +114,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -132,6 +137,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -152,6 +158,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeTruthy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -173,6 +180,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeTruthy();
expect(state.datasetsCount).toEqual(datasetsCount);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -193,6 +201,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -216,6 +225,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -242,6 +252,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -268,6 +279,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -288,6 +300,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(1);
expect(state.selectedData).toContain({ dname: 'toto', data:[1, 2] });
expect(state).not.toEqual(initialState);
@@ -300,6 +313,7 @@ describe('[SearchMultiple] Reducer', () => {
entities: { 'toto': { datasetName: 'toto', isLoading: false, isLoaded: true, data: [1, 2] }},
datasetsCountIsLoaded: true,
datasetsCount: [{ dname: 'toto', count: 2}],
+ datatableState: [{ dname: 'toto', accordionIsOpen: true }],
selectedData: [{ dname: 'toto', data:[1, 2] }]
};
const action = new searchMultipleActions.DestroyResultsAction();
@@ -316,6 +330,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -334,6 +349,7 @@ describe('[SearchMultiple] Reducer', () => {
datasetsCountIsLoading: true,
datasetsCountIsLoaded: true,
datasetsCount: [{ dname: 'toto', count: 2}],
+ datatableState: [{ dname: 'toto', accordionIsOpen: true }],
selectedData: [{ dname: 'toto', data:[1, 2] }]
};
const action = new searchMultipleActions.ResetSearchAction();
@@ -350,6 +366,7 @@ describe('[SearchMultiple] Reducer', () => {
expect(state.datasetsCountIsLoading).toBeFalsy();
expect(state.datasetsCountIsLoaded).toBeFalsy();
expect(state.datasetsCount.length).toEqual(0);
+ expect(state.datatableState.length).toEqual(0);
expect(state.selectedData.length).toEqual(0);
expect(state).not.toEqual(initialState);
});
@@ -438,6 +455,13 @@ describe('[SearchMultiple] Reducer', () => {
expect(fromSearchMultiple.getDatasetsCount(state).length).toEqual(0);
});
+ it('should get datatableState', () => {
+ const action = {} as searchMultipleActions.Actions;
+ const state = fromSearchMultiple.reducer(undefined, action);
+
+ expect(fromSearchMultiple.getDatatableState(state).length).toEqual(0);
+ });
+
it('should get selectedData', () => {
const action = {} as searchMultipleActions.Actions;
const state = fromSearchMultiple.reducer(undefined, action);
diff --git a/src/app/search-multiple/store/search-multiple.reducer.ts b/src/app/search-multiple/store/search-multiple.reducer.ts
index ebfc9c20358e6e594dfdd145c73cdc4cdf84eb84..318a89ed6fadf3da3f9358ffa71d1b069a8ee02d 100644
--- a/src/app/search-multiple/store/search-multiple.reducer.ts
+++ b/src/app/search-multiple/store/search-multiple.reducer.ts
@@ -28,6 +28,7 @@ export interface State extends EntityState {
datasetsCountIsLoading: boolean;
datasetsCountIsLoaded: boolean;
datasetsCount: DatasetCount[];
+ datatableState: { dname: string, accordionIsOpen: boolean }[];
selectedData: { dname: string, data: (string | number)[] }[];
}
@@ -56,6 +57,7 @@ export const initialState: State = adapter.getInitialState({
datasetsCountIsLoading: false,
datasetsCountIsLoaded: false,
datasetsCount: [],
+ datatableState: [],
selectedData: []
});
@@ -74,6 +76,7 @@ export function reducer(state: State = initialState, action: actions.Actions): S
return {
...state,
selectedDatasets: action.payload
+
};
case actions.CHANGE_STEP:
@@ -147,6 +150,12 @@ export function reducer(state: State = initialState, action: actions.Actions): S
}
} as Update, state);
+ case actions.UPDATE_DATATABLE_STATE:
+ return {
+ ...state,
+ datatableState: action.payload
+ };
+
case actions.UPDATE_SELECTED_DATA:
return {
...state,
@@ -158,6 +167,7 @@ export function reducer(state: State = initialState, action: actions.Actions): S
...state,
datasetsCountIsLoaded: false,
datasetsCount: [],
+ datatableState: [],
selectedData: []
});
@@ -183,4 +193,5 @@ export const getSelectedDatasets = (state: State) => state.selectedDatasets;
export const getDatasetsCountIsLoading = (state: State) => state.datasetsCountIsLoading;
export const getDatasetsCountIsLoaded = (state: State) => state.datasetsCountIsLoaded;
export const getDatasetsCount = (state: State) => state.datasetsCount;
+export const getDatatableState = (state: State) => state.datatableState;
export const getSelectedData = (state: State) => state.selectedData;
diff --git a/src/app/search-multiple/store/search-multiple.selector.spec.ts b/src/app/search-multiple/store/search-multiple.selector.spec.ts
index e72120ea74f4996e1442275b3d16cf7aca629bec..296fc8f62816c451bfeb2f5aa5cf1d32169215c1 100644
--- a/src/app/search-multiple/store/search-multiple.selector.spec.ts
+++ b/src/app/search-multiple/store/search-multiple.selector.spec.ts
@@ -87,6 +87,11 @@ describe('[SearchMultiple] Selector', () => {
expect(searchMultipleSelector.getDatasetsCount(state).length).toEqual(0);
});
+ it('should get datatableState', () => {
+ const state = { searchMultiple: { ...fromSearchMultiple.initialState }};
+ expect(searchMultipleSelector.getDatatableState(state).length).toEqual(0);
+ });
+
it('should get datasetsWithData', () => {
const state = { searchMultiple: { ...fromSearchMultiple.initialState }};
expect(searchMultipleSelector.getDatasetsWithData(state).length).toEqual(0);
@@ -97,7 +102,7 @@ describe('[SearchMultiple] Selector', () => {
expect(searchMultipleSelector.getAllData(state)).toEqual({});
});
- it('should get sSelectedData', () => {
+ it('should get selectedData', () => {
const state = { searchMultiple: { ...fromSearchMultiple.initialState }};
expect(searchMultipleSelector.getSelectedData(state).length).toEqual(0);
});
diff --git a/src/app/search-multiple/store/search-multiple.selector.ts b/src/app/search-multiple/store/search-multiple.selector.ts
index bc8e43f70b01ee8f03c8fde7a1b11be98e4be346..cfaa7ad0fb9e08bcbd8c346163b06d3f0941bb5f 100644
--- a/src/app/search-multiple/store/search-multiple.selector.ts
+++ b/src/app/search-multiple/store/search-multiple.selector.ts
@@ -91,6 +91,11 @@ export const getDatasetsCount = createSelector(
searchMultiple.getDatasetsCount
);
+export const getDatatableState = createSelector(
+ getSearchMultipleState,
+ searchMultiple.getDatatableState
+);
+
export const getDatasetsWithData = createSelector(
getSearchMultipleState,
searchMultiple.selectIds
diff --git a/src/app/search/components/result/datatable-tab.component.html b/src/app/search/components/result/datatable-tab.component.html
index e3cfd49430569371fd0f6ca15d85be65ab007af3..13370db92e6a5a276a70c0019b6d9aa77750abbd 100644
--- a/src/app/search/components/result/datatable-tab.component.html
+++ b/src/app/search/components/result/datatable-tab.component.html
@@ -1,5 +1,5 @@
- 0 && _dataLengthIsLoaded" [isAnimated]="true">
-
+ 0 && dataLengthIsLoaded" [isAnimated]="true">
+
Display result details
diff --git a/src/app/search/components/result/datatable-tab.component.spec.ts b/src/app/search/components/result/datatable-tab.component.spec.ts
index eec2bab3852025288e70b022c03287d9f0aa2713..89fff514037cd6c19001c9e20be480eb4de790b6 100644
--- a/src/app/search/components/result/datatable-tab.component.spec.ts
+++ b/src/app/search/components/result/datatable-tab.component.spec.ts
@@ -6,7 +6,7 @@ import { AccordionModule } from 'ngx-bootstrap/accordion';
import { DatatableTabComponent } from './datatable-tab.component';
import { Attribute, Dataset } from '../../../metamodel/model';
-import { Pagination, PaginationOrder } from '../../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../../shared/datatable/store/model';
import { ATTRIBUTE_LIST, DATASET_LIST } from '../../../../settings/test-data';
describe('[Search][Result] Component: DatatableTabComponent', () => {
@@ -21,6 +21,7 @@ describe('[Search][Result] Component: DatatableTabComponent', () => {
[searchData]='searchData'
[dataLengthIsLoaded]='dataLengthIsLoaded'
[dataLength]='dataLength'
+ [isDatatableOpen]='isDatatableOpen'
[selectedData]='selectedData'
[processWip]='processWip'
[processDone]='processDone'
@@ -37,6 +38,7 @@ describe('[Search][Result] Component: DatatableTabComponent', () => {
public searchData: any[];
public dataLengthIsLoaded: boolean;
public dataLength: number;
+ public isDatatableOpen: boolean = null;
public selectedData: any[];
public processWip: boolean;
public processDone: boolean;
@@ -82,6 +84,8 @@ describe('[Search][Result] Component: DatatableTabComponent', () => {
expect(testedComponent.isDatatableOpened()).toBeTruthy();
testedComponent.datasetName = 'cat_2';
expect(testedComponent.isDatatableOpened()).toBeFalsy();
+ testedComponent.isDatatableOpen = true;
+ expect(testedComponent.isDatatableOpened()).toBeTruthy();
});
it('#getDataset() should return dataset object', () => {
diff --git a/src/app/search/components/result/datatable-tab.component.ts b/src/app/search/components/result/datatable-tab.component.ts
index 81df08a2b1026c463e2fa9fc8754779b84e99aaa..23e8ada1a2dafeb4fa1c429146e26b27eaa2656b 100644
--- a/src/app/search/components/result/datatable-tab.component.ts
+++ b/src/app/search/components/result/datatable-tab.component.ts
@@ -10,7 +10,7 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { Attribute, Dataset } from '../../../metamodel/model';
-import { Pagination, PaginationOrder } from '../../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../../shared/datatable/store/model';
@Component({
selector: 'app-datatable-tab',
@@ -28,31 +28,15 @@ export class DatatableTabComponent {
@Input() datasetAttributeList: Attribute[];
@Input() outputList: number[];
@Input() searchData: any[];
- /**
- * Emits event to get data when result count is loaded.
- *
- * @param {boolean} dataLengthIsLoaded - Is result count loaded.
- */
- @Input()
- set dataLengthIsLoaded(dataLengthIsLoaded: boolean) {
- this._dataLengthIsLoaded = dataLengthIsLoaded;
- if (dataLengthIsLoaded) {
- const pagination: Pagination = {
- dname: this.datasetName,
- page: 1,
- nbItems: 10,
- sortedCol: this.datasetAttributeList.find(a => a.search_flag === 'ID').id,
- order: PaginationOrder.a
- };
- this.getSearchData.emit(pagination);
- }
- }
+ @Input() dataLengthIsLoaded: boolean;
@Input() dataLength: number;
+ @Input() isDatatableOpen: boolean;
@Input() selectedData: any[];
@Input() processWip: boolean;
@Input() processDone: boolean;
@Input() processId: string;
@Output() getSearchData: EventEmitter = new EventEmitter();
+ @Output() datatableIsOpen: EventEmitter = new EventEmitter();
@Output() addSelectedData: EventEmitter = new EventEmitter();
@Output() deleteSelectedData: EventEmitter = new EventEmitter();
@Output() executeProcess: EventEmitter = new EventEmitter();
@@ -65,11 +49,14 @@ export class DatatableTabComponent {
* @return boolean
*/
isDatatableOpened(): boolean {
- const config = this.getDataset().config;
- if (config !== null && 'opened_datatable' in config) {
- return config.opened_datatable;
+ if (this.isDatatableOpen === null) {
+ const config = this.getDataset().config;
+ if (config !== null && 'opened_datatable' in config) {
+ return config.opened_datatable;
+ }
+ return false;
}
- return false;
+ return this.isDatatableOpen;
}
/**
diff --git a/src/app/search/containers/result.component.html b/src/app/search/containers/result.component.html
index d8f04ac08b609883bbbfad913b7bf076d5aac050..a8a2b834a09210a46695a8846105cf3c72179883 100644
--- a/src/app/search/containers/result.component.html
+++ b/src/app/search/containers/result.component.html
@@ -44,8 +44,10 @@
[searchData]="searchData | async"
[dataLengthIsLoaded]="dataLengthIsLoaded | async"
[dataLength]="dataLength | async"
+ [isDatatableOpen]="isDatatableOpen | async"
[selectedData]="selectedData | async"
(getSearchData)="getSearchData($event)"
+ (datatableIsOpen)="datatableIsOpen($event)"
(addSelectedData)="addSearchData($event)"
(deleteSelectedData)="deleteSearchData($event)"
[processWip]="processWip | async"
diff --git a/src/app/search/containers/result.component.spec.ts b/src/app/search/containers/result.component.spec.ts
index c6518bb3d3502bcd8a06e8ae55f6502cf785ff06..f7a4e6bd57e7762639843e8050c53b7037202b57 100644
--- a/src/app/search/containers/result.component.spec.ts
+++ b/src/app/search/containers/result.component.spec.ts
@@ -13,7 +13,7 @@ import * as datasetActions from '../../metamodel/action/dataset.action';
import { Attribute, Category, Dataset, Family } from '../../metamodel/model';
import * as fromConeSearch from '../../shared/cone-search/store/cone-search.reducer';
import { ConeSearch } from '../../shared/cone-search/store/model';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
import { ScrollTopService } from '../../shared/service/sroll-top.service';
import { RouterLinkDirectiveStub } from '../../../settings/test-data/router-link-directive-stub';
@@ -60,6 +60,7 @@ describe('[Search] Container: ResultComponent', () => {
@Input() outputList: number[];
@Input() searchData: any[];
@Input() dataLength: number;
+ @Input() isDatatableOpen: boolean;
@Input() selectedData: any[];
@Input() processWip: boolean;
@Input() processDone: boolean;
@@ -138,6 +139,14 @@ describe('[Search] Container: ResultComponent', () => {
expect(spy).toHaveBeenCalledWith(retrieveDataAction);
});
+ it('#datatableIsOpen() should dispatch IsDatatableOpenedAction', () => {
+ const isDatatableOpenedAction = new searchActions.IsDatatableOpenedAction(true);
+ const spy = spyOn(store, 'dispatch');
+ component.datatableIsOpen(true);
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith(isDatatableOpenedAction);
+ });
+
it('#addSearchData() should dispatch AddSelectedDataAction', () => {
const addSelectedDataAction = new searchActions.AddSelectedDataAction('toto');
const spy = spyOn(store, 'dispatch');
diff --git a/src/app/search/containers/result.component.ts b/src/app/search/containers/result.component.ts
index be31b07830813ce8679bf2020a9b62fe6e7f8b78..ac7e9ce132596a8ff6615e7ffa23af385b8c113b 100644
--- a/src/app/search/containers/result.component.ts
+++ b/src/app/search/containers/result.component.ts
@@ -22,7 +22,7 @@ import * as metamodelSelector from '../../metamodel/selectors';
import { Dataset, Attribute, Family, Category } from '../../metamodel/model';
import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
import { ConeSearch } from '../../shared/cone-search/store/model';
-import { Pagination } from '../../shared/datatable/model';
+import { Pagination } from '../../shared/datatable/store/model';
import { ScrollTopService } from '../../shared/service/sroll-top.service';
/**
@@ -65,6 +65,7 @@ export class ResultComponent implements OnInit, OnDestroy {
public searchData: Observable;
public dataLengthIsLoaded: Observable;
public dataLength: Observable;
+ public isDatatableOpen: Observable;
public selectedData: Observable;
public queryParams: Observable;
public processWip: Observable;
@@ -87,6 +88,7 @@ export class ResultComponent implements OnInit, OnDestroy {
this.searchData = this.store.select(searchSelector.getSearchData);
this.dataLengthIsLoaded = this.store.select(searchSelector.getDataLengthIsLoaded);
this.dataLength = this.store.select(searchSelector.getDataLength);
+ this.isDatatableOpen = this.store.select(searchSelector.getDatatableIsOpen);
this.selectedData = this.store.select(searchSelector.getSelectedData);
this.queryParams = this.store.select(searchSelector.getQueryParams);
this.processWip = this.store.select(searchSelector.getProcessWip);
@@ -127,6 +129,15 @@ export class ResultComponent implements OnInit, OnDestroy {
this.store.dispatch(new searchActions.RetrieveDataAction(params));
}
+ /**
+ * Dispatches action to change datatable opened status.
+ *
+ * @param {boolean} status - The status.
+ */
+ datatableIsOpen(status: boolean): void {
+ this.store.dispatch(new searchActions.IsDatatableOpenedAction(status));
+ }
+
/**
* Dispatches action to add the given data ID to the selected data.
*
diff --git a/src/app/search/store/search.action.spec.ts b/src/app/search/store/search.action.spec.ts
index 141cec9ec20eb3c945fa11241b621ab32e80724f..4acdc8d4b99f5d8c599d4a3eb1da08f5228a1d2b 100644
--- a/src/app/search/store/search.action.spec.ts
+++ b/src/app/search/store/search.action.spec.ts
@@ -1,6 +1,6 @@
import * as searchActions from './search.action';
import { Criterion } from './model';
-import { Pagination, PaginationOrder } from '../../shared/datatable/model';
+import { Pagination, PaginationOrder } from '../../shared/datatable/store/model';
import { CRITERIA_LIST } from '../../../settings/test-data';
describe('[Search] Action', () => {
@@ -108,6 +108,12 @@ describe('[Search] Action', () => {
expect(action.type).toEqual(searchActions.GET_DATA_LENGTH_FAIL);
});
+ it('should create IsDatatableOpenedAction', () => {
+ const action = new searchActions.IsDatatableOpenedAction(true);
+ expect(action.type).toEqual(searchActions.IS_DATATABLE_OPENED);
+ expect(action.payload).toBeTruthy();
+ });
+
it('should create AddSelectedDataAction', () => {
const action = new searchActions.AddSelectedDataAction(1);
expect(action.type).toEqual(searchActions.ADD_SELECTED_DATA);
diff --git a/src/app/search/store/search.action.ts b/src/app/search/store/search.action.ts
index ba78624ff8b2f14252dbce4332a2116dc94ccf82..3bef7c34d6d405a125db3a067c9d8096d9ac571e 100644
--- a/src/app/search/store/search.action.ts
+++ b/src/app/search/store/search.action.ts
@@ -10,7 +10,7 @@
import { Action } from '@ngrx/store';
import { Criterion } from './model';
-import { Pagination } from '../../shared/datatable/model';
+import { Pagination } from '../../shared/datatable/store/model';
export const INIT_SEARCH_BY_URL = '[Search] Init Search By Url';
@@ -31,6 +31,7 @@ export const RETRIEVE_DATA_FAIL = '[Search] Retrieve Data Fail';
export const GET_DATA_LENGTH = '[Search] Get Data Length';
export const GET_DATA_LENGTH_SUCCESS = '[Search] Get Data Length Success';
export const GET_DATA_LENGTH_FAIL = '[Search] Get Data Length Fail';
+export const IS_DATATABLE_OPENED = '[Search] Is Datatable Opened';
export const ADD_SELECTED_DATA = '[Search] Add Selected Data';
export const DELETE_SELECTED_DATA = '[Search] Delete Selected Data';
export const EXECUTE_PROCESS = '[Search] Execute Process';
@@ -238,6 +239,17 @@ export class GetDataLengthFailAction implements Action {
constructor(public payload: {} = null) { }
}
+/**
+ * @class
+ * @classdesc IsDatatableOpenedAction action.
+ * @readonly
+ */
+export class IsDatatableOpenedAction implements Action {
+ readonly type = IS_DATATABLE_OPENED;
+
+ constructor(public payload: boolean) { }
+}
+
/**
* @class
* @classdesc AddSelectedDataAction action.
@@ -345,6 +357,7 @@ export type Actions
| GetDataLengthAction
| GetDataLengthSuccessAction
| GetDataLengthFailAction
+ | IsDatatableOpenedAction
| AddSelectedDataAction
| DeleteSelectedDataAction
| ExecuteProcessAction
diff --git a/src/app/search/store/search.effects.ts b/src/app/search/store/search.effects.ts
index 9c34fd835c4b2752315df50b5ced0eedc3c2a2d8..a62571b86a6207f98dce80ae039f4f645665115d 100644
--- a/src/app/search/store/search.effects.ts
+++ b/src/app/search/store/search.effects.ts
@@ -28,6 +28,7 @@ import { Option } from '../../metamodel/model';
import * as fromConeSearch from '../../shared/cone-search/store/cone-search.reducer';
import * as coneSearchActions from '../../shared/cone-search/store/cone-search.action';
import { ConeSearch } from '../../shared/cone-search/store/model';
+import * as datatableActions from '../../shared/datatable/store/datatable.action';
import * as utils from '../../shared/utils';
import { getCriterionStr } from '../../shared/utils';
@@ -89,7 +90,8 @@ export class SearchEffects {
ofType(searchActions.NEW_SEARCH),
switchMap((action: searchActions.NewSearchAction) => [
new searchActions.SelectDatasetAction(action.payload),
- new coneSearchActions.DeleteConeSearchAction()
+ new coneSearchActions.DeleteConeSearchAction(),
+ new datatableActions.ResetDatatableAction()
])
);
diff --git a/src/app/search/store/search.reducer.spec.ts b/src/app/search/store/search.reducer.spec.ts
index 1d68224e99bda1ed43976ccb6d6062816d3e930c..6b2e07e4235152c4347552e7cd91c2d41179fa82 100644
--- a/src/app/search/store/search.reducer.spec.ts
+++ b/src/app/search/store/search.reducer.spec.ts
@@ -30,6 +30,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -55,6 +56,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -80,6 +82,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -105,6 +108,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -130,6 +134,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -155,6 +160,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -180,6 +186,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -206,6 +213,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -233,6 +241,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -260,6 +269,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -287,6 +297,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -314,6 +325,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -340,6 +352,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeTruthy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -365,6 +378,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeTruthy();
expect(state.dataLength).toBe(12);
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -390,6 +404,33 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
+ expect(state.selectedData.length).toEqual(0);
+ expect(state.processWip).toBeFalsy();
+ expect(state.processDone).toBeFalsy();
+ expect(state.processId).toBeNull();
+ expect(state).not.toEqual(initialState);
+ });
+
+ it('should set dataLengthIsLoading to true', () => {
+ const { initialState } = fromSearch;
+ const action = new searchActions.IsDatatableOpenedAction(true);
+ const state = fromSearch.reducer(initialState, action);
+
+ expect(state.pristine).toBeTruthy();
+ expect(state.currentStep).toBeNull()
+ expect(state.datasetName).toBeNull();
+ expect(state.criteriaStepChecked).toBeFalsy();
+ expect(state.outputStepChecked).toBeFalsy();
+ expect(state.resultStepChecked).toBeFalsy();
+ expect(state.coneSearchAdded).toBeFalsy();
+ expect(state.criteriaList.length).toEqual(0);
+ expect(state.outputList.length).toEqual(0);
+ expect(state.searchData.length).toEqual(0);
+ expect(state.dataLengthIsLoading).toBeFalsy();
+ expect(state.dataLengthIsLoaded).toBeFalsy();
+ expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeTruthy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -415,6 +456,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(1);
expect(state.selectedData).toContain(1);
expect(state.processWip).toBeFalsy();
@@ -441,6 +483,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(1);
expect(state.selectedData).toContain('data_1');
expect(state.selectedData).not.toContain('data_2');
@@ -468,6 +511,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeTruthy();
expect(state.processDone).toBeFalsy();
@@ -493,6 +537,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -518,6 +563,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeTruthy();
@@ -548,6 +594,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -577,6 +624,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -600,6 +648,7 @@ describe('[Search] Reducer', () => {
dataLengthIsLoading: true,
dataLengthIsLoaded: true,
dataLength: 3,
+ datatableIsOpen: true,
selectedData: [1],
processWip: true,
processDone: true,
@@ -621,6 +670,7 @@ describe('[Search] Reducer', () => {
expect(state.dataLengthIsLoading).toBeFalsy();
expect(state.dataLengthIsLoaded).toBeFalsy();
expect(state.dataLength).toBeNull();
+ expect(state.datatableIsOpen).toBeFalsy();
expect(state.selectedData.length).toEqual(0);
expect(state.processWip).toBeFalsy();
expect(state.processDone).toBeFalsy();
@@ -719,6 +769,13 @@ describe('[Search] Reducer', () => {
expect(fromSearch.getDataLength(state)).toBeNull();
});
+ it('should get datatableIsOpened', () => {
+ const action = {} as searchActions.Actions;
+ const state = fromSearch.reducer(undefined, action);
+
+ expect(fromSearch.getDatatableIsOpen(state)).toBeFalsy();
+ });
+
it('should get selectedData', () => {
const action = {} as searchActions.Actions;
const state = fromSearch.reducer(undefined, action);
diff --git a/src/app/search/store/search.reducer.ts b/src/app/search/store/search.reducer.ts
index a7bc23d21d67ad4f6187f65c3a1886911ab3a0b0..c9a24c084a3740e9f54b71976d8b4fafed1fa431 100644
--- a/src/app/search/store/search.reducer.ts
+++ b/src/app/search/store/search.reducer.ts
@@ -29,6 +29,7 @@ export interface State {
dataLengthIsLoading: boolean;
dataLengthIsLoaded: boolean;
dataLength: number;
+ datatableIsOpen: boolean;
selectedData: any[];
processWip: boolean;
processDone: boolean;
@@ -49,6 +50,7 @@ export const initialState: State = {
dataLengthIsLoading: false,
dataLengthIsLoaded: false,
dataLength: null,
+ datatableIsOpen: null,
selectedData: [],
processWip: false,
processDone: false,
@@ -158,6 +160,12 @@ export function reducer(state: State = initialState, action: actions.Actions): S
dataLengthIsLoading: false
};
+ case actions.IS_DATATABLE_OPENED:
+ return {
+ ...state,
+ datatableIsOpen: action.payload
+ };
+
case actions.ADD_SELECTED_DATA:
return {
...state,
@@ -226,6 +234,7 @@ export const getSearchData = (state: State) => state.searchData;
export const getDataLengthIsLoading = (state: State) => state.dataLengthIsLoading;
export const getDataLengthIsLoaded = (state: State) => state.dataLengthIsLoaded;
export const getDataLength = (state: State) => state.dataLength;
+export const getDatatableIsOpen = (state: State) => state.datatableIsOpen;
export const getSelectedData = (state: State) => state.selectedData;
export const getProcessWip = (state: State) => state.processWip;
export const getProcessDone = (state: State) => state.processDone;
diff --git a/src/app/search/store/search.selector.spec.ts b/src/app/search/store/search.selector.spec.ts
index 24e371588c92c388c807fd8099ba818279d8ab74..62d625e9c68f1919d25a4db8d7cfb425705922b0 100644
--- a/src/app/search/store/search.selector.spec.ts
+++ b/src/app/search/store/search.selector.spec.ts
@@ -61,6 +61,11 @@ describe('[Search] Selector', () => {
expect(searchSelector.getDataLength(state)).toBeNull();
});
+ it('should get datatableIsOpen', () => {
+ const state = { search: { ...fromSearch.initialState }};
+ expect(searchSelector.getDatatableIsOpen(state)).toBeFalsy();
+ });
+
it('should get selectedData', () => {
const state = { search: { ...fromSearch.initialState }};
expect(searchSelector.getSelectedData(state).length).toEqual(0);
diff --git a/src/app/search/store/search.selector.ts b/src/app/search/store/search.selector.ts
index 4826b2c494a550704ebfde630d91a5f3ad8f28e1..29ac093977df8d67990e7b5f57ce6c247ac26953 100644
--- a/src/app/search/store/search.selector.ts
+++ b/src/app/search/store/search.selector.ts
@@ -62,7 +62,6 @@ export const getOutputList = createSelector(
search.getOutputList
);
-
export const getOutputListEmpty = createSelector(
getOutputList,
(
@@ -91,6 +90,11 @@ export const getDataLength = createSelector(
search.getDataLength
);
+export const getDatatableIsOpen = createSelector(
+ getSearchState,
+ search.getDatatableIsOpen
+);
+
export const getSelectedData = createSelector(
getSearchState,
search.getSelectedData
diff --git a/src/app/shared/cone-search/conainers/cone-search.component.spec.ts b/src/app/shared/cone-search/conainers/cone-search.component.spec.ts
index 439630b81ee0f906de6f88477d4615992cf56123..e68bb1c4c8d7db2e0d15bec563b83dbab78f732e 100644
--- a/src/app/shared/cone-search/conainers/cone-search.component.spec.ts
+++ b/src/app/shared/cone-search/conainers/cone-search.component.spec.ts
@@ -9,7 +9,7 @@ import { ConeSearch, Resolver } from '../store/model';
import * as fromConeSearch from '../store/cone-search.reducer';
import * as coneSearchActions from '../store/cone-search.action';
-describe('[Shared][ConeSearch] Component: ConeSearchComponent', () => {
+describe('[Shared][ConeSearch] Container: ConeSearchComponent', () => {
@Component({
selector: `app-host`,
template: ` `
diff --git a/src/app/shared/cone-search/store/cone-search.action.spec.ts b/src/app/shared/cone-search/store/cone-search.action.spec.ts
index e1339dd764d5252f95f22ed6193059aa48d0b82d..d8db902b2559597c8ff91f04489d0f7b5216d62e 100644
--- a/src/app/shared/cone-search/store/cone-search.action.spec.ts
+++ b/src/app/shared/cone-search/store/cone-search.action.spec.ts
@@ -1,47 +1,47 @@
-import * as searchActions from '../store/cone-search.action';
+import * as coneSearchActions from '../store/cone-search.action';
import { ConeSearch, Resolver } from './model';
describe('[Shared][ConeSearch] Action', () => {
it('should create RetrieveCoordinatesAction', () => {
- const action = new searchActions.RetrieveCoordinatesAction('toto');
- expect(action.type).toEqual(searchActions.RETRIEVE_COORDINATES);
+ const action = new coneSearchActions.RetrieveCoordinatesAction('toto');
+ expect(action.type).toEqual(coneSearchActions.RETRIEVE_COORDINATES);
expect(action.payload).toEqual('toto');
});
it('should create RetrieveCoordinatesSuccessAction', () => {
const resolver: Resolver = { name: 'toto', ra: 1, dec: 2 };
- const action = new searchActions.RetrieveCoordinatesSuccessAction(resolver);
- expect(action.type).toEqual(searchActions.RETRIEVE_COORDINATES_SUCCESS);
+ const action = new coneSearchActions.RetrieveCoordinatesSuccessAction(resolver);
+ expect(action.type).toEqual(coneSearchActions.RETRIEVE_COORDINATES_SUCCESS);
expect(action.payload).toEqual(resolver);
});
it('should create RetrieveCoordinatesFailAction', () => {
- const action = new searchActions.RetrieveCoordinatesFailAction(null);
- expect(action.type).toEqual(searchActions.RETRIEVE_COORDINATES_FAIL);
+ const action = new coneSearchActions.RetrieveCoordinatesFailAction(null);
+ expect(action.type).toEqual(coneSearchActions.RETRIEVE_COORDINATES_FAIL);
expect(action.payload).toBeNull();
});
it('should create DeleteResolverAction', () => {
- const action = new searchActions.DeleteResolverAction();
- expect(action.type).toEqual(searchActions.DELETE_RESOLVER);
+ const action = new coneSearchActions.DeleteResolverAction();
+ expect(action.type).toEqual(coneSearchActions.DELETE_RESOLVER);
});
it('should create AddConeSearchAction', () => {
const coneSearch: ConeSearch = { ra: 1, dec: 2, radius: 3 };
- const action = new searchActions.AddConeSearchAction(coneSearch);
- expect(action.type).toEqual(searchActions.ADD_CONE_SEARCH);
+ const action = new coneSearchActions.AddConeSearchAction(coneSearch);
+ expect(action.type).toEqual(coneSearchActions.ADD_CONE_SEARCH);
expect(action.payload).toEqual(coneSearch);
});
it('should create AddConeSearchFromUrlAction', () => {
const coneSearch: ConeSearch = { ra: 1, dec: 2, radius: 3 };
- const action = new searchActions.AddConeSearchFromUrlAction(coneSearch);
- expect(action.type).toEqual(searchActions.ADD_CONE_SEARCH_FROM_URL);
+ const action = new coneSearchActions.AddConeSearchFromUrlAction(coneSearch);
+ expect(action.type).toEqual(coneSearchActions.ADD_CONE_SEARCH_FROM_URL);
expect(action.payload).toEqual(coneSearch);
});
it('should create DeleteConeSearchAction', () => {
- const action = new searchActions.DeleteConeSearchAction();
- expect(action.type).toEqual(searchActions.DELETE_CONE_SEARCH);
+ const action = new coneSearchActions.DeleteConeSearchAction();
+ expect(action.type).toEqual(coneSearchActions.DELETE_CONE_SEARCH);
});
});
diff --git a/src/app/shared/datatable/components/detail.component.css b/src/app/shared/datatable/components/detail.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..5c1a8a2110f66b6348624a6e469dbc16d29da3d4
--- /dev/null
+++ b/src/app/shared/datatable/components/detail.component.css
@@ -0,0 +1,18 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+a:visited {
+ color: purple;
+ border-color: purple;
+}
+
+a:hover {
+ color: #fff;
+ border-color: #007bff;
+}
diff --git a/src/app/shared/datatable/components/detail.component.html b/src/app/shared/datatable/components/detail.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..c350700a4802d57dd2ab2c813f293cc13cde4801
--- /dev/null
+++ b/src/app/shared/datatable/components/detail.component.html
@@ -0,0 +1,6 @@
+
+ {{ value }}
+
diff --git a/src/app/shared/datatable/renderer/detail.component.spec.ts b/src/app/shared/datatable/components/detail.component.spec.ts
similarity index 89%
rename from src/app/shared/datatable/renderer/detail.component.spec.ts
rename to src/app/shared/datatable/components/detail.component.spec.ts
index eb79818742ce02ac9ed386dbdad2dc9c6f98008a..b959bae1907203c97e3be42ca15cb9a9e87c03c9 100644
--- a/src/app/shared/datatable/renderer/detail.component.spec.ts
+++ b/src/app/shared/datatable/components/detail.component.spec.ts
@@ -3,7 +3,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { DetailComponent } from './detail.component';
-describe('[Search][Result][Renderer] Component: DetailComponent', () => {
+describe('[Shared][Datatable] Component: DetailComponent', () => {
let component: DetailComponent;
let fixture: ComponentFixture;
diff --git a/src/app/shared/datatable/renderer/detail.component.ts b/src/app/shared/datatable/components/detail.component.ts
similarity index 74%
rename from src/app/shared/datatable/renderer/detail.component.ts
rename to src/app/shared/datatable/components/detail.component.ts
index fd042143f0c5085a989e7606d3b85ed3ff3ab928..84c98d6f24ce16195f5f91f5c0b1f6f5f82d3442 100644
--- a/src/app/shared/datatable/renderer/detail.component.ts
+++ b/src/app/shared/datatable/components/detail.component.ts
@@ -7,9 +7,9 @@
* file that was distributed with this source code.
*/
-import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
-import { RendererConfig } from "../../../metamodel/model";
+import { RendererConfig } from '../../../metamodel/model';
/**
* Interface for detail renderer configuration.
@@ -25,6 +25,7 @@ interface DetailConfig extends RendererConfig {
@Component({
selector: 'app-detail',
templateUrl: 'detail.component.html',
+ styleUrls: ['detail.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
/**
@@ -35,4 +36,5 @@ export class DetailComponent {
@Input() value: string | number;
@Input() datasetName: string;
@Input() config: DetailConfig;
+ @Output() addVisited: EventEmitter = new EventEmitter();
}
diff --git a/src/app/shared/datatable/components/download.component.html b/src/app/shared/datatable/components/download.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..10943498488130571107e5f40b4d2c8838861f2d
--- /dev/null
+++ b/src/app/shared/datatable/components/download.component.html
@@ -0,0 +1,4 @@
+
+ {{ config.text }}
+
+
\ No newline at end of file
diff --git a/src/app/shared/datatable/renderer/download.component.spec.ts b/src/app/shared/datatable/components/download.component.spec.ts
similarity index 91%
rename from src/app/shared/datatable/renderer/download.component.spec.ts
rename to src/app/shared/datatable/components/download.component.spec.ts
index 3e35a3e4b8fab14d0dea1196c6163ebbe80d8bee..4d34eef9f284de37ce6bec7b7be81f46161cb84f 100644
--- a/src/app/shared/datatable/renderer/download.component.spec.ts
+++ b/src/app/shared/datatable/components/download.component.spec.ts
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DownloadComponent } from './download.component';
import { environment } from '../../../../environments/environment';
-describe('[Search][Result][Renderer] Component: DownloadComponent', () => {
+describe('[Shared][Datatable] Component: DownloadComponent', () => {
let component: DownloadComponent;
let fixture: ComponentFixture;
diff --git a/src/app/shared/datatable/renderer/download.component.ts b/src/app/shared/datatable/components/download.component.ts
similarity index 96%
rename from src/app/shared/datatable/renderer/download.component.ts
rename to src/app/shared/datatable/components/download.component.ts
index 131b452eacb017b940b1525b641a1980aa8bae54..eec94cfaef983303b6e00e78de91a72ba2979c9b 100644
--- a/src/app/shared/datatable/renderer/download.component.ts
+++ b/src/app/shared/datatable/components/download.component.ts
@@ -10,7 +10,7 @@
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
import { RendererConfig } from '../../../metamodel/model';
-import { getHost } from "../../utils";
+import { getHost } from '../../utils';
/**
* Interface for download renderer configuration.
diff --git a/src/app/shared/datatable/renderer/image.component.html b/src/app/shared/datatable/components/image.component.html
similarity index 100%
rename from src/app/shared/datatable/renderer/image.component.html
rename to src/app/shared/datatable/components/image.component.html
diff --git a/src/app/shared/datatable/renderer/image.component.spec.ts b/src/app/shared/datatable/components/image.component.spec.ts
similarity index 92%
rename from src/app/shared/datatable/renderer/image.component.spec.ts
rename to src/app/shared/datatable/components/image.component.spec.ts
index dfa40c87e3a914a56b7ff02d3504e970655bc428..ad91235df49df86edc772a45136311e3079fb082 100644
--- a/src/app/shared/datatable/renderer/image.component.spec.ts
+++ b/src/app/shared/datatable/components/image.component.spec.ts
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ImageComponent } from './image.component';
import { environment } from '../../../../environments/environment';
-describe('[Search][Result][Renderer] Component: ImageComponent', () => {
+describe('[Shared][Datatable] Component: ImageComponent', () => {
let component: ImageComponent;
let fixture: ComponentFixture;
diff --git a/src/app/shared/datatable/renderer/image.component.ts b/src/app/shared/datatable/components/image.component.ts
similarity index 96%
rename from src/app/shared/datatable/renderer/image.component.ts
rename to src/app/shared/datatable/components/image.component.ts
index 99e4cca654e0c46d6298cca168a55bd10ed220a7..eb4405756f1761433698ca0b2219f85696abbb56 100644
--- a/src/app/shared/datatable/renderer/image.component.ts
+++ b/src/app/shared/datatable/components/image.component.ts
@@ -10,7 +10,7 @@
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
import { RendererConfig } from '../../../metamodel/model';
-import { getHost } from "../../utils";
+import { getHost } from '../../utils';
/**
* Interface for image renderer configuration.
diff --git a/src/app/shared/datatable/renderer/json.component.html b/src/app/shared/datatable/components/json.component.html
similarity index 91%
rename from src/app/shared/datatable/renderer/json.component.html
rename to src/app/shared/datatable/components/json.component.html
index 95f6bf5cbac116ba299049a5cbbf7c9be31549c9..82d6886eea7550a18f54adf2f984f773f6c1dfa9 100644
--- a/src/app/shared/datatable/renderer/json.component.html
+++ b/src/app/shared/datatable/components/json.component.html
@@ -1,6 +1,4 @@
-
- JSON
-
+JSON