From 731948d99f4e4922f7739ed43101a7d73e73149d Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Wed, 20 Jan 2021 10:37:38 +0100 Subject: [PATCH 01/16] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd6091..7e4f5fb 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 -- GitLab From c173f0cb0fae48b2f6bbcb1ed222bef0b8b32afb Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Wed, 20 Jan 2021 12:15:09 +0100 Subject: [PATCH 02/16] Refactoring datatable folder => DONE --- .../result/datasets-result.component.spec.ts | 2 +- .../components/result/datasets-result.component.ts | 2 +- .../containers/result-multiple.component.spec.ts | 2 +- .../containers/result-multiple.component.ts | 2 +- .../store/search-multiple.action.spec.ts | 2 +- .../search-multiple/store/search-multiple.action.ts | 2 +- .../search-multiple/store/search-multiple.effects.ts | 2 +- .../store/search-multiple.reducer.spec.ts | 2 +- .../result/datatable-tab.component.spec.ts | 2 +- .../components/result/datatable-tab.component.ts | 2 +- src/app/search/containers/result.component.spec.ts | 2 +- src/app/search/containers/result.component.ts | 2 +- src/app/search/store/search.action.spec.ts | 2 +- src/app/search/store/search.action.ts | 2 +- src/app/search/store/search.reducer.ts | 2 ++ .../conainers/cone-search.component.spec.ts | 2 +- .../{renderer => components}/detail.component.html | 0 .../detail.component.spec.ts | 2 +- .../{renderer => components}/detail.component.ts | 0 .../{renderer => components}/download.component.html | 0 .../download.component.spec.ts | 2 +- .../{renderer => components}/download.component.ts | 0 .../{renderer => components}/image.component.html | 0 .../{renderer => components}/image.component.spec.ts | 2 +- .../{renderer => components}/image.component.ts | 0 .../{renderer => components}/json.component.html | 0 .../{renderer => components}/json.component.spec.ts | 2 +- .../{renderer => components}/json.component.ts | 0 .../{renderer => components}/link.component.html | 0 .../{renderer => components}/link.component.spec.ts | 2 +- .../{renderer => components}/link.component.ts | 0 .../{ => containers}/datatable.component.css | 0 .../{ => containers}/datatable.component.html | 0 .../{ => containers}/datatable.component.spec.ts | 6 +++--- .../{ => containers}/datatable.component.ts | 4 ++-- src/app/shared/datatable/index.ts | 12 ++++++------ src/app/shared/datatable/{ => store}/model/index.ts | 0 .../datatable/{ => store}/model/pagination.model.ts | 0 38 files changed, 33 insertions(+), 31 deletions(-) rename src/app/shared/datatable/{renderer => components}/detail.component.html (100%) rename src/app/shared/datatable/{renderer => components}/detail.component.spec.ts (89%) rename src/app/shared/datatable/{renderer => components}/detail.component.ts (100%) rename src/app/shared/datatable/{renderer => components}/download.component.html (100%) rename src/app/shared/datatable/{renderer => components}/download.component.spec.ts (91%) rename src/app/shared/datatable/{renderer => components}/download.component.ts (100%) rename src/app/shared/datatable/{renderer => components}/image.component.html (100%) rename src/app/shared/datatable/{renderer => components}/image.component.spec.ts (92%) rename src/app/shared/datatable/{renderer => components}/image.component.ts (100%) rename src/app/shared/datatable/{renderer => components}/json.component.html (100%) rename src/app/shared/datatable/{renderer => components}/json.component.spec.ts (91%) rename src/app/shared/datatable/{renderer => components}/json.component.ts (100%) rename src/app/shared/datatable/{renderer => components}/link.component.html (100%) rename src/app/shared/datatable/{renderer => components}/link.component.spec.ts (94%) rename src/app/shared/datatable/{renderer => components}/link.component.ts (100%) rename src/app/shared/datatable/{ => containers}/datatable.component.css (100%) rename src/app/shared/datatable/{ => containers}/datatable.component.html (100%) rename src/app/shared/datatable/{ => containers}/datatable.component.spec.ts (97%) rename src/app/shared/datatable/{ => containers}/datatable.component.ts (97%) rename src/app/shared/datatable/{ => store}/model/index.ts (100%) rename src/app/shared/datatable/{ => store}/model/pagination.model.ts (100%) 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 965b62d..48c9100 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 e913ee0..a9f5137 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'; 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 34263ec..872a73d 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 64b5ed3..f82bbe0 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'; /** 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 9a89055..fcb27a0 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', () => { diff --git a/src/app/search-multiple/store/search-multiple.action.ts b/src/app/search-multiple/store/search-multiple.action.ts index c97e804..75b7e7b 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'; diff --git a/src/app/search-multiple/store/search-multiple.effects.ts b/src/app/search-multiple/store/search-multiple.effects.ts index 6ff23ce..89f9198 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 b066962..fd5c88b 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', () => { 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 eec2bab..0d5a6e8 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', () => { diff --git a/src/app/search/components/result/datatable-tab.component.ts b/src/app/search/components/result/datatable-tab.component.ts index 81df08a..06a4182 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', diff --git a/src/app/search/containers/result.component.spec.ts b/src/app/search/containers/result.component.spec.ts index c6518bb..63eaa31 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'; diff --git a/src/app/search/containers/result.component.ts b/src/app/search/containers/result.component.ts index be31b07..d7f8c95 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'; /** diff --git a/src/app/search/store/search.action.spec.ts b/src/app/search/store/search.action.spec.ts index 141cec9..acfe75f 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', () => { diff --git a/src/app/search/store/search.action.ts b/src/app/search/store/search.action.ts index ba78624..0ea12f3 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'; diff --git a/src/app/search/store/search.reducer.ts b/src/app/search/store/search.reducer.ts index a7bc23d..513ccee 100644 --- a/src/app/search/store/search.reducer.ts +++ b/src/app/search/store/search.reducer.ts @@ -29,6 +29,8 @@ export interface State { dataLengthIsLoading: boolean; dataLengthIsLoaded: boolean; dataLength: number; + // openedDatatable: boolean; + // nb intems, datatable page en cours et object séléctionné selectedData: any[]; processWip: boolean; processDone: boolean; 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 439630b..e68bb1c 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/datatable/renderer/detail.component.html b/src/app/shared/datatable/components/detail.component.html similarity index 100% rename from src/app/shared/datatable/renderer/detail.component.html rename to src/app/shared/datatable/components/detail.component.html 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 eb79818..b959bae 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 100% rename from src/app/shared/datatable/renderer/detail.component.ts rename to src/app/shared/datatable/components/detail.component.ts diff --git a/src/app/shared/datatable/renderer/download.component.html b/src/app/shared/datatable/components/download.component.html similarity index 100% rename from src/app/shared/datatable/renderer/download.component.html rename to src/app/shared/datatable/components/download.component.html 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 3e35a3e..4d34eef 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 100% rename from src/app/shared/datatable/renderer/download.component.ts rename to src/app/shared/datatable/components/download.component.ts 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 dfa40c8..ad91235 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 100% rename from src/app/shared/datatable/renderer/image.component.ts rename to src/app/shared/datatable/components/image.component.ts diff --git a/src/app/shared/datatable/renderer/json.component.html b/src/app/shared/datatable/components/json.component.html similarity index 100% rename from src/app/shared/datatable/renderer/json.component.html rename to src/app/shared/datatable/components/json.component.html diff --git a/src/app/shared/datatable/renderer/json.component.spec.ts b/src/app/shared/datatable/components/json.component.spec.ts similarity index 91% rename from src/app/shared/datatable/renderer/json.component.spec.ts rename to src/app/shared/datatable/components/json.component.spec.ts index 322a6e8..9904410 100644 --- a/src/app/shared/datatable/renderer/json.component.spec.ts +++ b/src/app/shared/datatable/components/json.component.spec.ts @@ -6,7 +6,7 @@ import { BsModalService } from 'ngx-bootstrap/modal'; import { JsonComponent } from './json.component'; -describe('[Search][Result][Renderer] Component: JsonComponent', () => { +describe('[Shared][Datatable] Component: JsonComponent', () => { let component: JsonComponent; let fixture: ComponentFixture; diff --git a/src/app/shared/datatable/renderer/json.component.ts b/src/app/shared/datatable/components/json.component.ts similarity index 100% rename from src/app/shared/datatable/renderer/json.component.ts rename to src/app/shared/datatable/components/json.component.ts diff --git a/src/app/shared/datatable/renderer/link.component.html b/src/app/shared/datatable/components/link.component.html similarity index 100% rename from src/app/shared/datatable/renderer/link.component.html rename to src/app/shared/datatable/components/link.component.html diff --git a/src/app/shared/datatable/renderer/link.component.spec.ts b/src/app/shared/datatable/components/link.component.spec.ts similarity index 94% rename from src/app/shared/datatable/renderer/link.component.spec.ts rename to src/app/shared/datatable/components/link.component.spec.ts index 4b2ffd8..0b31d1a 100644 --- a/src/app/shared/datatable/renderer/link.component.spec.ts +++ b/src/app/shared/datatable/components/link.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { LinkComponent } from './link.component'; -describe('[Search][Result][Renderer] Component: LinkComponent', () => { +describe('[Shared][Datatable] Component: LinkComponent', () => { let component: LinkComponent; let fixture: ComponentFixture; diff --git a/src/app/shared/datatable/renderer/link.component.ts b/src/app/shared/datatable/components/link.component.ts similarity index 100% rename from src/app/shared/datatable/renderer/link.component.ts rename to src/app/shared/datatable/components/link.component.ts diff --git a/src/app/shared/datatable/datatable.component.css b/src/app/shared/datatable/containers/datatable.component.css similarity index 100% rename from src/app/shared/datatable/datatable.component.css rename to src/app/shared/datatable/containers/datatable.component.css diff --git a/src/app/shared/datatable/datatable.component.html b/src/app/shared/datatable/containers/datatable.component.html similarity index 100% rename from src/app/shared/datatable/datatable.component.html rename to src/app/shared/datatable/containers/datatable.component.html diff --git a/src/app/shared/datatable/datatable.component.spec.ts b/src/app/shared/datatable/containers/datatable.component.spec.ts similarity index 97% rename from src/app/shared/datatable/datatable.component.spec.ts rename to src/app/shared/datatable/containers/datatable.component.spec.ts index c29f358..4d8133d 100644 --- a/src/app/shared/datatable/datatable.component.spec.ts +++ b/src/app/shared/datatable/containers/datatable.component.spec.ts @@ -5,10 +5,10 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { AccordionModule } from 'ngx-bootstrap/accordion'; import { DatatableComponent } from './datatable.component'; -import { ATTRIBUTE_LIST, DATASET } from '../../../settings/test-data'; -import { Pagination, PaginationOrder } from './model'; +import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; +import { Pagination, PaginationOrder } from '../store/model'; -describe('[Search][Result] Component: DatatableComponent', () => { +describe('[Shared][Datatable] Container: DatatableComponent', () => { @Component({ selector: 'app-img', template: '' }) class ImgStubComponent { @Input() src: string; diff --git a/src/app/shared/datatable/datatable.component.ts b/src/app/shared/datatable/containers/datatable.component.ts similarity index 97% rename from src/app/shared/datatable/datatable.component.ts rename to src/app/shared/datatable/containers/datatable.component.ts index 6b57619..d752510 100644 --- a/src/app/shared/datatable/datatable.component.ts +++ b/src/app/shared/datatable/containers/datatable.component.ts @@ -9,8 +9,8 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Attribute, Dataset } from '../../metamodel/model'; -import { Pagination, PaginationOrder } from './model'; +import { Attribute, Dataset } from '../../../metamodel/model'; +import { Pagination, PaginationOrder } from '../store/model'; @Component({ diff --git a/src/app/shared/datatable/index.ts b/src/app/shared/datatable/index.ts index 782dd80..b8f5247 100644 --- a/src/app/shared/datatable/index.ts +++ b/src/app/shared/datatable/index.ts @@ -1,9 +1,9 @@ -import { DatatableComponent } from './datatable.component'; -import { DetailComponent } from './renderer/detail.component'; -import { ImageComponent } from './renderer/image.component'; -import { JsonComponent } from './renderer/json.component'; -import { LinkComponent } from './renderer/link.component'; -import { DownloadComponent } from './renderer/download.component'; +import { DatatableComponent } from './containers/datatable.component'; +import { DetailComponent } from './components/detail.component'; +import { ImageComponent } from './components/image.component'; +import { JsonComponent } from './components/json.component'; +import { LinkComponent } from './components/link.component'; +import { DownloadComponent } from './components/download.component'; export const datatableComponents = [ DatatableComponent, diff --git a/src/app/shared/datatable/model/index.ts b/src/app/shared/datatable/store/model/index.ts similarity index 100% rename from src/app/shared/datatable/model/index.ts rename to src/app/shared/datatable/store/model/index.ts diff --git a/src/app/shared/datatable/model/pagination.model.ts b/src/app/shared/datatable/store/model/pagination.model.ts similarity index 100% rename from src/app/shared/datatable/model/pagination.model.ts rename to src/app/shared/datatable/store/model/pagination.model.ts -- GitLab From 1906a61544966e454c3e3ebef4dee0ea3acb9626 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Wed, 20 Jan 2021 14:28:00 +0100 Subject: [PATCH 03/16] Prepare dataset store => DONE --- src/app/search/store/search.reducer.ts | 1 - .../store/cone-search.action.spec.ts | 30 +++++++++---------- src/app/shared/shared.module.ts | 6 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/app/search/store/search.reducer.ts b/src/app/search/store/search.reducer.ts index 513ccee..65dfaa0 100644 --- a/src/app/search/store/search.reducer.ts +++ b/src/app/search/store/search.reducer.ts @@ -30,7 +30,6 @@ export interface State { dataLengthIsLoaded: boolean; dataLength: number; // openedDatatable: boolean; - // nb intems, datatable page en cours et object séléctionné selectedData: any[]; processWip: boolean; processDone: boolean; 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 e1339dd..d8db902 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/shared.module.ts b/src/app/shared/shared.module.ts index d9171df..498e3a7 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -29,10 +29,11 @@ import { PrettyOperatorPipe } from './pretty-operator.pipe'; import { NgSelectModule } from '@ng-select/ng-select'; import { InlineSVGModule } from 'ng-inline-svg'; import { coneSearchComponents } from './cone-search'; -import { reducer } from './cone-search/store/cone-search.reducer'; +import { reducer as coneSearchReducer } from './cone-search/store/cone-search.reducer'; import { ConeSearchEffects } from './cone-search/store/cone-search.effects'; import { ConeSearchService } from './cone-search/store/cone-search.service'; import { datatableComponents } from './datatable'; +import { reducer as datatableReducer } from './datatable/store/datatable.reducer'; @NgModule({ imports: [ @@ -52,7 +53,8 @@ import { datatableComponents } from './datatable'; NgxJsonViewerModule, InlineSVGModule.forRoot(), RouterModule, - StoreModule.forFeature('coneSearch', reducer), + StoreModule.forFeature('coneSearch', coneSearchReducer), + StoreModule.forFeature('datatable', datatableReducer), EffectsModule.forFeature([ConeSearchEffects]) ], exports: [ -- GitLab From d0326fc6bdb7459292db18ab1e623f307a8a86e8 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Wed, 20 Jan 2021 14:28:23 +0100 Subject: [PATCH 04/16] Prepare dataset store => DONE --- .../datatable/store/datatable.action.spec.ts | 25 ++++ .../datatable/store/datatable.action.ts | 66 +++++++++ .../datatable/store/datatable.effects.ts | 125 ++++++++++++++++++ .../datatable/store/datatable.reducer.spec.ts | 125 ++++++++++++++++++ .../datatable/store/datatable.reducer.ts | 83 ++++++++++++ .../store/datatable.selector.spec.ts | 19 +++ .../datatable/store/datatable.selector.ts | 29 ++++ 7 files changed, 472 insertions(+) create mode 100644 src/app/shared/datatable/store/datatable.action.spec.ts create mode 100644 src/app/shared/datatable/store/datatable.action.ts create mode 100644 src/app/shared/datatable/store/datatable.effects.ts create mode 100644 src/app/shared/datatable/store/datatable.reducer.spec.ts create mode 100644 src/app/shared/datatable/store/datatable.reducer.ts create mode 100644 src/app/shared/datatable/store/datatable.selector.spec.ts create mode 100644 src/app/shared/datatable/store/datatable.selector.ts diff --git a/src/app/shared/datatable/store/datatable.action.spec.ts b/src/app/shared/datatable/store/datatable.action.spec.ts new file mode 100644 index 0000000..77e94e2 --- /dev/null +++ b/src/app/shared/datatable/store/datatable.action.spec.ts @@ -0,0 +1,25 @@ +import * as datatableActions from '../store/datatable.action'; + +describe('[Shared][Datatable] Action', () => { + it('should create ChangePageAction', () => { + const action = new datatableActions.ChangePageAction(2); + expect(action.type).toEqual(datatableActions.CHANGE_PAGE); + expect(action.payload).toEqual(2); + }); + + it('should create ChangeNbItemsAction', () => { + const action = new datatableActions.ChangeNbItemsAction(2); + expect(action.type).toEqual(datatableActions.CHANGE_NB_ITEMS); + expect(action.payload).toEqual(2); + }); + + it('should create AddVisitedAction', () => { + const action = new datatableActions.AddVisitedAction(2); + expect(action.type).toEqual(datatableActions.ADD_VISITED); + expect(action.payload).toEqual(2); + }); + it('should create ResetDatatableAction', () => { + const action = new datatableActions.ResetDatatableAction(); + expect(action.type).toEqual(datatableActions.RESET_DATATABLE); + }); +}); diff --git a/src/app/shared/datatable/store/datatable.action.ts b/src/app/shared/datatable/store/datatable.action.ts new file mode 100644 index 0000000..02c7ffa --- /dev/null +++ b/src/app/shared/datatable/store/datatable.action.ts @@ -0,0 +1,66 @@ +/** + * 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. + */ + +import { Action } from '@ngrx/store'; + +export const CHANGE_PAGE = '[Datatable] Change Page'; +export const CHANGE_NB_ITEMS = '[Datatable] Change Nb Items'; +export const ADD_VISITED = '[Datatable] Add Visited'; +export const RESET_DATATABLE = '[Datatable] Reset Datatable'; + + +/** + * @class + * @classdesc ChangePageAction action. + * @readonly + */ +export class ChangePageAction implements Action { + readonly type = CHANGE_PAGE; + + constructor(public payload: number) { } +} + +/** + * @class + * @classdesc ChangeNbItemsAction action. + * @readonly + */ +export class ChangeNbItemsAction implements Action { + readonly type = CHANGE_NB_ITEMS; + + constructor(public payload: number) { } +} + +/** + * @class + * @classdesc AddVisitedAction action. + * @readonly + */ +export class AddVisitedAction implements Action { + readonly type = ADD_VISITED; + + constructor(public payload: number) { } +} + +/** + * @class + * @classdesc ResetDatatableAction action. + * @readonly + */ +export class ResetDatatableAction implements Action { + readonly type = RESET_DATATABLE; + + constructor(public payload: {} = null) { } +} + +export type Actions + = ChangePageAction + | ChangeNbItemsAction + | AddVisitedAction + | ResetDatatableAction; diff --git a/src/app/shared/datatable/store/datatable.effects.ts b/src/app/shared/datatable/store/datatable.effects.ts new file mode 100644 index 0000000..8f96661 --- /dev/null +++ b/src/app/shared/datatable/store/datatable.effects.ts @@ -0,0 +1,125 @@ +/** + * 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. + */ + +import { Injectable } from '@angular/core'; +import { FormControl, Validators } from '@angular/forms'; + +import * as fromRouter from '@ngrx/router-store'; +import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Action, Store } from '@ngrx/store'; +import { of } from 'rxjs'; +import { map, tap, switchMap, withLatestFrom, catchError } from 'rxjs/operators'; +import { ToastrService } from 'ngx-toastr'; + +import * as datatableActions from './datatable.action'; +import * as fromDatatable from './datatable.reducer'; +import * as utils from '../../utils'; + + +@Injectable() +/** + * @class + * @classdesc Datatable effects. + */ +export class DatatableEffects { + constructor( + private actions$: Actions, + private toastr: ToastrService, + private store$: Store<{ + router: fromRouter.RouterReducerState, + coneSearch: fromDatatable.State + }> + ) { } + + /** + * Calls retrieveCoordinates function and raises success or fail action depending on request result. + */ + // @Effect() + // retrieveCoordinatesAction$ = this.actions$.pipe( + // ofType(coneSearchActions.RETRIEVE_COORDINATES), + // withLatestFrom(this.store$), + // switchMap(([action, state]) => { + // const retrieveCoordinatesAction = action as coneSearchActions.RetrieveCoordinatesAction; + // return this.coneSearchService.retrieveCoordinates(retrieveCoordinatesAction.payload).pipe( + // map((response) => { + // const parser = new DOMParser(); + // const xml = parser.parseFromString(response,'text/xml'); + // if (xml.getElementsByTagName('Resolver').length === 0) { + // const name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue; + // return new coneSearchActions.RetrieveCoordinatesFailAction(name); + // } + // const name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue; + // const ra = +xml.getElementsByTagName('jradeg')[0].childNodes[0].nodeValue; + // const dec = +xml.getElementsByTagName('jdedeg')[0].childNodes[0].nodeValue; + // return new coneSearchActions.RetrieveCoordinatesSuccessAction({ name, ra, dec }); + // }), + // catchError(() => of(new coneSearchActions.RetrieveCoordinatesFailAction(null))) + // ); + // }) + // ); + + /** + * Fills store cone search. + */ + // @Effect() + // retrieveCoordinatesSuccessAction$ = this.actions$.pipe( + // ofType(coneSearchActions.RETRIEVE_COORDINATES_SUCCESS), + // withLatestFrom(this.store$), + // map(([action, state]) => { + // const retrieveCoordinatesSuccessAction = action as coneSearchActions.RetrieveCoordinatesSuccessAction; + // const coneSearch: ConeSearch = { + // ra: retrieveCoordinatesSuccessAction.payload.ra, + // dec: retrieveCoordinatesSuccessAction.payload.dec, + // radius: state.coneSearch.coneSearch.radius + // }; + // return new coneSearchActions.AddConeSearchAction(coneSearch); + // }) + // ); + + /** + * Displays a retrieve coordinates error notification. + */ + // @Effect({ dispatch: false }) + // retrieveCoordinatesFailAction$ = this.actions$.pipe( + // ofType(coneSearchActions.RETRIEVE_COORDINATES_FAIL), + // tap(action => { + // const retrieveCoordinatesFailAction = action as coneSearchActions.RetrieveCoordinatesFailAction; + // if (retrieveCoordinatesFailAction.payload) { + // this.toastr.error(retrieveCoordinatesFailAction.payload + ' not found'); + // } else { + // this.toastr.error('Connection to Sesame Name Resolver failed', 'Resolver Failed!'); + // } + // }) + // ); + + /** + * Fills store cone search form url or a not valid notification. + */ + // @Effect() + // addConeSearchFromUrlAction$ = this.actions$.pipe( + // ofType(coneSearchActions.ADD_CONE_SEARCH_FROM_URL), + // switchMap(action => { + // const addConeSearchFromUrlAction = action as coneSearchActions.AddConeSearchFromUrlAction; + // let raForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(0, 360)]); + // raForm.setValue(addConeSearchFromUrlAction.payload.ra); + // let decForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(-90, 90)]); + // decForm.setValue(addConeSearchFromUrlAction.payload.dec); + // let radiusForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(0, 150)]); + // radiusForm.setValue(addConeSearchFromUrlAction.payload.radius); + // if (!raForm.errors && !decForm.errors && !radiusForm.errors) { + // const actions: Action[] = []; + // actions.push(new coneSearchActions.AddConeSearchAction(addConeSearchFromUrlAction.payload)); + // return actions; + // } else { + // this.toastr.error('Cone search from URL is not valid', 'Not valid position!'); + // return of(); + // } + // }) + // ); +} diff --git a/src/app/shared/datatable/store/datatable.reducer.spec.ts b/src/app/shared/datatable/store/datatable.reducer.spec.ts new file mode 100644 index 0000000..2eca75d --- /dev/null +++ b/src/app/shared/datatable/store/datatable.reducer.spec.ts @@ -0,0 +1,125 @@ +import * as fromDatatable from './datatable.reducer'; +import * as datatableActions from './datatable.action'; + +describe('[Shared][Datatable] Reducer', () => { + it('should return init state', () => { + const { initialState } = fromDatatable; + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(state).toBe(initialState); + }); + + // it('should set resolverWip to true', () => { + // const { initialState } = fromConeSearch; + // const action = new coneSearchActions.RetrieveCoordinatesAction('toto'); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeTruthy(); + // expect(state.resolver).toBeNull(); + // expect(state.coneSearch.ra).toBeNull(); + // expect(state.coneSearch.dec).toBeNull(); + // expect(state.coneSearch.radius).toBeNull(); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should set resolver ans resolverWip to false', () => { + // const resolver: Resolver = { name: 'toto', ra: 1, dec: 2 }; + // const initialState = { + // ...fromConeSearch.initialState, + // resolverWip: true + // }; + // const action = new coneSearchActions.RetrieveCoordinatesSuccessAction(resolver); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeFalsy(); + // expect(state.resolver).toEqual(resolver); + // expect(state.coneSearch.ra).toBeNull(); + // expect(state.coneSearch.dec).toBeNull(); + // expect(state.coneSearch.radius).toBeNull(); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should set resolverWip to false', () => { + // const initialState = { + // ...fromConeSearch.initialState, + // resolverWip: true + // }; + // const action = new coneSearchActions.RetrieveCoordinatesFailAction(null); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeFalsy(); + // expect(state.resolver).toBeNull(); + // expect(state.coneSearch.ra).toBeNull(); + // expect(state.coneSearch.dec).toBeNull(); + // expect(state.coneSearch.radius).toBeNull(); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should unset resolver', () => { + // const resolver: Resolver = { name: 'toto', ra: 1, dec: 2 }; + // const initialState = { + // ...fromConeSearch.initialState, + // resolver + // }; + // const action = new coneSearchActions.DeleteResolverAction(); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeFalsy(); + // expect(state.resolver).toBeNull(); + // expect(state.coneSearch.ra).toBeNull(); + // expect(state.coneSearch.dec).toBeNull(); + // expect(state.coneSearch.radius).toBeNull(); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should set coneSearch', () => { + // const coneSearch = { ra: 1, dec: 2, radius: 3 } as ConeSearch; + // const { initialState } = fromConeSearch; + // const action = new coneSearchActions.AddConeSearchAction(coneSearch); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeFalsy(); + // expect(state.resolver).toBeNull(); + // expect(state.coneSearch.ra).toEqual(1); + // expect(state.coneSearch.dec).toEqual(2); + // expect(state.coneSearch.radius).toEqual(3); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should unset coneSearch', () => { + // const coneSearch = { ra: 1, dec: 2, radius: 3 } as ConeSearch; + // const initialState = { ...fromConeSearch.initialState, coneSearch }; + // const action = new coneSearchActions.DeleteConeSearchAction(); + // const state = fromConeSearch.reducer(initialState, action); + // + // expect(state.resolverWip).toBeFalsy(); + // expect(state.resolver).toBeNull(); + // expect(state.coneSearch.ra).toBeNull(); + // expect(state.coneSearch.dec).toBeNull(); + // expect(state.coneSearch.radius).toBeNull(); + // expect(state).not.toEqual(initialState); + // }); + // + // it('should get resolverWip', () => { + // const action = {} as coneSearchActions.Actions; + // const state = fromConeSearch.reducer(undefined, action); + // + // expect(fromConeSearch.getResolverWip(state)).toBeFalsy(); + // }); + // + // it('should get resolver', () => { + // const action = {} as coneSearchActions.Actions; + // const state = fromConeSearch.reducer(undefined, action); + // + // expect(fromConeSearch.getResolver(state)).toBeNull(); + // }); + // + // it('should get coneSearch', () => { + // const action = {} as coneSearchActions.Actions; + // const state = fromConeSearch.reducer(undefined, action); + // const expectedConeSearch: ConeSearch = { ra: null, dec: null, radius: null }; + // + // expect(fromConeSearch.getConeSearch(state)).toEqual(expectedConeSearch); + // }); +}); diff --git a/src/app/shared/datatable/store/datatable.reducer.ts b/src/app/shared/datatable/store/datatable.reducer.ts new file mode 100644 index 0000000..ab9c3da --- /dev/null +++ b/src/app/shared/datatable/store/datatable.reducer.ts @@ -0,0 +1,83 @@ +/** + * 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. + */ + +import * as actions from './datatable.action'; + +/** + * Interface for datatable state. + * + * @interface State + */ +export interface State { + page: number; + nbItems: number; + visited: number[]; +} + +export const initialState: State = { + page: 1, + nbItems: 10, + visited: [] +}; + +/** + * Reduces state. + * + * @param {State} state - The state. + * @param {actions} action - The action. + * + * @return State + */ +export function reducer(state: State = initialState, action: actions.Actions): State { + switch (action.type) { + // case actions.RETRIEVE_COORDINATES: + // return { + // ...state, + // resolverWip: true + // }; + // + // case actions.RETRIEVE_COORDINATES_SUCCESS: + // return { + // ...state, + // resolverWip: false, + // resolver: action.payload + // }; + // + // case actions.RETRIEVE_COORDINATES_FAIL: + // return { + // ...state, + // resolverWip: false + // }; + // + // case actions.DELETE_RESOLVER: + // return { + // ...state, + // resolver: null + // }; + // + // case actions.ADD_CONE_SEARCH: + // return { + // ...state, + // coneSearch: action.payload + // }; + // + // case actions.DELETE_CONE_SEARCH: + // return { + // ...state, + // coneSearch: { ra: null, dec: null, radius: null } + // }; + + default: + return state; + } +} + +export const getPage = (state: State) => state.page; +export const getNbItems = (state: State) => state.nbItems; +export const getVisited = (state: State) => state.visited; diff --git a/src/app/shared/datatable/store/datatable.selector.spec.ts b/src/app/shared/datatable/store/datatable.selector.spec.ts new file mode 100644 index 0000000..1e057dd --- /dev/null +++ b/src/app/shared/datatable/store/datatable.selector.spec.ts @@ -0,0 +1,19 @@ +import * as datatableSelector from './datatable.selector'; +import * as fromDatatable from './datatable.reducer'; + +describe('[Shared][Datatable] Selector', () => { + it('should get page', () => { + const state = { datatable: { ...fromDatatable.initialState }}; + expect(datatableSelector.getPage(state)).toEqual(1); + }); + + it('should get nbItems', () => { + const state = { datatable: { ...fromDatatable.initialState }}; + expect(datatableSelector.getNbItems(state)).toEqual(10); + }); + + it('should get visited', () => { + const state = { datatable: { ...fromDatatable.initialState }}; + expect(datatableSelector.getVisited(state).length).toEqual(0); + }); +}); \ No newline at end of file diff --git a/src/app/shared/datatable/store/datatable.selector.ts b/src/app/shared/datatable/store/datatable.selector.ts new file mode 100644 index 0000000..df59dcc --- /dev/null +++ b/src/app/shared/datatable/store/datatable.selector.ts @@ -0,0 +1,29 @@ +/** + * 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. + */ + +import { createSelector, createFeatureSelector } from '@ngrx/store'; + +import * as datatable from './datatable.reducer'; + +export const getDatatableState = createFeatureSelector('datatable'); + +export const getPage = createSelector( + getDatatableState, + datatable.getPage +); + +export const getNbItems = createSelector( + getDatatableState, + datatable.getNbItems +); + +export const getVisited = createSelector( + getDatatableState, + datatable.getVisited +); -- GitLab From d726e75d44b0c168277fe9bb71fd7f9975adafef Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Wed, 20 Jan 2021 16:13:23 +0100 Subject: [PATCH 05/16] Save is search state the datatable accordion status => DONE --- .../result/datatable-tab.component.html | 2 +- .../result/datatable-tab.component.spec.ts | 4 ++ .../result/datatable-tab.component.ts | 17 ++++-- .../search/containers/result.component.html | 2 + .../containers/result.component.spec.ts | 9 +++ src/app/search/containers/result.component.ts | 11 ++++ src/app/search/store/search.action.spec.ts | 6 ++ src/app/search/store/search.action.ts | 13 +++++ src/app/search/store/search.reducer.spec.ts | 57 +++++++++++++++++++ src/app/search/store/search.reducer.ts | 10 +++- src/app/search/store/search.selector.spec.ts | 5 ++ src/app/search/store/search.selector.ts | 6 +- 12 files changed, 135 insertions(+), 7 deletions(-) diff --git a/src/app/search/components/result/datatable-tab.component.html b/src/app/search/components/result/datatable-tab.component.html index e3cfd49..3269ea6 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 @@ - + diff --git a/src/app/shared/datatable/components/table-pagination.component.spec.ts b/src/app/shared/datatable/components/table-pagination.component.spec.ts index b2b6e5b..f022cba 100644 --- a/src/app/shared/datatable/components/table-pagination.component.spec.ts +++ b/src/app/shared/datatable/components/table-pagination.component.spec.ts @@ -1,53 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Component, Input } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { AccordionModule } from 'ngx-bootstrap/accordion'; - -import { TablePaginationComponent } from './datatable.component'; -import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; -import { Pagination, PaginationOrder } from '../store/model'; - -describe('[Shared][Datatable] Container: DatatableComponent', () => { - @Component({ selector: 'app-img', template: '' }) - class ImgStubComponent { - @Input() src: string; - } - - @Component({ selector: 'app-thumbnail', template: '' }) - class ThumbnailStubComponent { - @Input() src: string; - @Input() attributeName: string; - } - - @Component({ selector: 'app-link', template: '' }) - class LinkStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-btn', template: '' }) - class BtnStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-detail', template: '' }) - class DetailStubComponent { - @Input() style: string; - @Input() datasetName: string; - @Input() data: string | number; - } - - @Component({ selector: 'app-download', template: '' }) - class DownloadStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-json-renderer', template: '' }) - class JsonStubComponent { - @Input() attributeName: string; - @Input() json: string; - } +import { TablePaginationComponent } from './table-pagination.component'; +describe('[Shared][Datatable] Component: TablePaginationComponent', () => { @Component({ selector: 'pagination', template: '' }) class PaginationStubComponent { @Input() totalItems: number; @@ -63,16 +19,8 @@ describe('[Shared][Datatable] Container: DatatableComponent', () => { TestBed.configureTestingModule({ declarations: [ TablePaginationComponent, - ImgStubComponent, - ThumbnailStubComponent, - LinkStubComponent, - BtnStubComponent, - DetailStubComponent, - DownloadStubComponent, - JsonStubComponent, PaginationStubComponent - ], - imports: [AccordionModule.forRoot(), BrowserAnimationsModule] + ] }); fixture = TestBed.createComponent(TablePaginationComponent); component = fixture.componentInstance; @@ -81,140 +29,5 @@ describe('[Shared][Datatable] Container: DatatableComponent', () => { it('should create the component', () => { expect(component).toBeTruthy(); }); - - it('#requiredParams() should return if required params are loaded', () => { - component.attributeList = ATTRIBUTE_LIST; - component.outputList = [1]; - component.dataLength = 1; - expect(component.requiredParams()).toBeTruthy(); - component.dataLength = undefined; - expect(component.requiredParams()).toBeFalsy(); - component.dataLength = 1; - component.outputList = []; - expect(component.requiredParams()).toBeFalsy(); - component.outputList = [1]; - component.attributeList = [] - expect(component.requiredParams()).toBeFalsy(); - }); - - it('#noSelectedData() should return true if no selectedData', () => { - component.selectedData = []; - expect(component.noSelectedData()).toBeTruthy(); - }); - - it('#noSelectedData() should return false if there are selectedData', () => { - component.selectedData = [123456]; - expect(component.noSelectedData()).toBeFalsy(); - }); - - it('#getOutputList() should return filtered output list', () => { - component.outputList = [2] - component.attributeList = ATTRIBUTE_LIST; - expect(component.getOutputList().length).toBe(1); - }); - - it('#toggleSelection(datum) should return add datum to selectedData', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = []; - component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456)); - component.toggleSelection(datum); - }); - - it('#toggleSelection(datum) should return remove datum to selectedData', () => { - const datum = { label_one: 123456 }; - component.selectedData = [123456]; - component.attributeList = ATTRIBUTE_LIST; - component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456)); - component.toggleSelection(datum); - }); - - it('#isSelected(datum) should return true datum is selected', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = [123456]; - expect(component.isSelected(datum)).toBeTruthy(); - }); - - it('#isSelected(datum) should return false datum is not selected', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = []; - expect(component.isSelected(datum)).toBeFalsy(); - }); - - it('#changePage() should change page value and raise getData event', () => { - component.dataset = DATASET; - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - const expectedPagination: Pagination = { - dname: 'cat_1', - page: 2, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.changePage(2); - }); - - it('#changeNbItems() should change nbItems value and raise getData event', () => { - component.dataset = DATASET; - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - const expectedPagination: Pagination = { - dname: 'cat_1', - page: 1, - nbItems: 20, - sortedCol: 1, - order: PaginationOrder.a - } - component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.changeNbItems(20); - }); - - it('#sort() should raise getData event with correct parameters', () => { - component.dataset = DATASET; - component.sortedOrder = PaginationOrder.a; - let expectedPagination: Pagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - let subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - subscribtion.unsubscribe(); - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - expectedPagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.d - } - subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - subscribtion.unsubscribe(); - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.d; - expectedPagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - }); - - it('#ngOnInit() should init sortedCol value', () => { - component.attributeList = ATTRIBUTE_LIST; - component.ngOnInit(); - expect(component.sortedCol).toEqual(1); - }); }); diff --git a/src/app/shared/datatable/components/table-pagination.component.ts b/src/app/shared/datatable/components/table-pagination.component.ts index 4679ea6..bf54f22 100644 --- a/src/app/shared/datatable/components/table-pagination.component.ts +++ b/src/app/shared/datatable/components/table-pagination.component.ts @@ -9,12 +9,9 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { Pagination, PaginationOrder } from '../store/model'; - @Component({ selector: 'app-table-pagination', - templateUrl: 'table-pagination.component.html', - styleUrls: ['table-pagination.component.css'] + templateUrl: 'table-pagination.component.html' }) /** * @class @@ -25,78 +22,7 @@ export class TablePaginationComponent { @Input() nbItems: number; @Output() changeTablePagination: EventEmitter<{ page: number, nbItems: number }> = new EventEmitter(); - /** - * Emits event to change datatable page. - * - * @param {number} page - The datatable page number. - * @param {number} nbItems - The items number to be displayed per page. - * - * @fires EventEmitter - */ - // changeDatatable(page: number, nbItems: number): void { - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: page, - // nbItems: nbItems, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); - // } - - /** - * Emits event to change datatable page. - * - * @param {number} page - The page number to access. - * - * @fires EventEmitter - */ - changePage(page: number): void { - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: page, - // nbItems: nb, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); - // this.page = nb; - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: page, - // nbItems: this.nbItems, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); + log() { + console.error(this.nbItems); } - - /** - * Emits event to change datatable displayed items. - * - * @param {number} nbItems - The number of items to display. - * - * @fires EventEmitter - */ - // changeNbItems(nbItems: number): void { - // this.page.subscribe(p => { - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: p, - // nbItems: nbItems, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); - // }); - // // this.nbItems = nb; - // // const pagination: Pagination = { - // // dname: this.dataset.name, - // // page: this.page, - // // nbItems: this.nbItems, - // // sortedCol: this.sortedCol, - // // order: PaginationOrder.a - // // }; - // // this.getData.emit(pagination); - // } } diff --git a/src/app/shared/datatable/containers/datatable.component.css b/src/app/shared/datatable/containers/datatable.component.css index 569fb3c..435295a 100644 --- a/src/app/shared/datatable/containers/datatable.component.css +++ b/src/app/shared/datatable/containers/datatable.component.css @@ -19,10 +19,6 @@ ul { margin-bottom: 0; } -.custom-select { - width: fit-content; -} - .clickable:hover { cursor: pointer; background-color: #F7F7F7; diff --git a/src/app/shared/datatable/containers/datatable.component.html b/src/app/shared/datatable/containers/datatable.component.html index cfbe405..d316274 100644 --- a/src/app/shared/datatable/containers/datatable.component.html +++ b/src/app/shared/datatable/containers/datatable.component.html @@ -102,7 +102,12 @@
- +
+ + @@ -111,13 +116,13 @@ - +
- - - - - + + diff --git a/src/app/shared/datatable/containers/datatable.component.spec.ts b/src/app/shared/datatable/containers/datatable.component.spec.ts index 4d8133d..a1e8dab 100644 --- a/src/app/shared/datatable/containers/datatable.component.spec.ts +++ b/src/app/shared/datatable/containers/datatable.component.spec.ts @@ -1,220 +1,220 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Component, Input } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -import { AccordionModule } from 'ngx-bootstrap/accordion'; - -import { DatatableComponent } from './datatable.component'; -import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; -import { Pagination, PaginationOrder } from '../store/model'; - -describe('[Shared][Datatable] Container: DatatableComponent', () => { - @Component({ selector: 'app-img', template: '' }) - class ImgStubComponent { - @Input() src: string; - } - - @Component({ selector: 'app-thumbnail', template: '' }) - class ThumbnailStubComponent { - @Input() src: string; - @Input() attributeName: string; - } - - @Component({ selector: 'app-link', template: '' }) - class LinkStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-btn', template: '' }) - class BtnStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-detail', template: '' }) - class DetailStubComponent { - @Input() style: string; - @Input() datasetName: string; - @Input() data: string | number; - } - - @Component({ selector: 'app-download', template: '' }) - class DownloadStubComponent { - @Input() href: string; - } - - @Component({ selector: 'app-json-renderer', template: '' }) - class JsonStubComponent { - @Input() attributeName: string; - @Input() json: string; - } - - @Component({ selector: 'pagination', template: '' }) - class PaginationStubComponent { - @Input() totalItems: number; - @Input() boundaryLinks: boolean; - @Input() rotate: boolean; - @Input() maxSize: number; - } - - let component: DatatableComponent; - let fixture: ComponentFixture; - - beforeEach(() => { - TestBed.configureTestingModule({ - declarations: [ - DatatableComponent, - ImgStubComponent, - ThumbnailStubComponent, - LinkStubComponent, - BtnStubComponent, - DetailStubComponent, - DownloadStubComponent, - JsonStubComponent, - PaginationStubComponent - ], - imports: [AccordionModule.forRoot(), BrowserAnimationsModule] - }); - fixture = TestBed.createComponent(DatatableComponent); - component = fixture.componentInstance; - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - it('#requiredParams() should return if required params are loaded', () => { - component.attributeList = ATTRIBUTE_LIST; - component.outputList = [1]; - component.dataLength = 1; - expect(component.requiredParams()).toBeTruthy(); - component.dataLength = undefined; - expect(component.requiredParams()).toBeFalsy(); - component.dataLength = 1; - component.outputList = []; - expect(component.requiredParams()).toBeFalsy(); - component.outputList = [1]; - component.attributeList = [] - expect(component.requiredParams()).toBeFalsy(); - }); - - it('#noSelectedData() should return true if no selectedData', () => { - component.selectedData = []; - expect(component.noSelectedData()).toBeTruthy(); - }); - - it('#noSelectedData() should return false if there are selectedData', () => { - component.selectedData = [123456]; - expect(component.noSelectedData()).toBeFalsy(); - }); - - it('#getOutputList() should return filtered output list', () => { - component.outputList = [2] - component.attributeList = ATTRIBUTE_LIST; - expect(component.getOutputList().length).toBe(1); - }); - - it('#toggleSelection(datum) should return add datum to selectedData', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = []; - component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456)); - component.toggleSelection(datum); - }); - - it('#toggleSelection(datum) should return remove datum to selectedData', () => { - const datum = { label_one: 123456 }; - component.selectedData = [123456]; - component.attributeList = ATTRIBUTE_LIST; - component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456)); - component.toggleSelection(datum); - }); - - it('#isSelected(datum) should return true datum is selected', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = [123456]; - expect(component.isSelected(datum)).toBeTruthy(); - }); - - it('#isSelected(datum) should return false datum is not selected', () => { - const datum = { label_one: 123456 }; - component.attributeList = ATTRIBUTE_LIST; - component.selectedData = []; - expect(component.isSelected(datum)).toBeFalsy(); - }); - - it('#changePage() should change page value and raise getData event', () => { - component.dataset = DATASET; - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - const expectedPagination: Pagination = { - dname: 'cat_1', - page: 2, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.changePage(2); - }); - - it('#changeNbItems() should change nbItems value and raise getData event', () => { - component.dataset = DATASET; - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - const expectedPagination: Pagination = { - dname: 'cat_1', - page: 1, - nbItems: 20, - sortedCol: 1, - order: PaginationOrder.a - } - component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.changeNbItems(20); - }); - - it('#sort() should raise getData event with correct parameters', () => { - component.dataset = DATASET; - component.sortedOrder = PaginationOrder.a; - let expectedPagination: Pagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - let subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - subscribtion.unsubscribe(); - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.a; - expectedPagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.d - } - subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - subscribtion.unsubscribe(); - component.sortedCol = 1; - component.sortedOrder = PaginationOrder.d; - expectedPagination = { - dname: 'cat_1', - page: 1, - nbItems: 10, - sortedCol: 1, - order: PaginationOrder.a - } - subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); - component.sort(1); - }); - - it('#ngOnInit() should init sortedCol value', () => { - component.attributeList = ATTRIBUTE_LIST; - component.ngOnInit(); - expect(component.sortedCol).toEqual(1); - }); -}); - +// import { ComponentFixture, TestBed } from '@angular/core/testing'; +// import { Component, Input } from '@angular/core'; +// import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +// +// import { AccordionModule } from 'ngx-bootstrap/accordion'; +// +// import { DatatableComponent } from './datatable.component'; +// import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; +// import { Pagination, PaginationOrder } from '../store/model'; +// +// describe('[Shared][Datatable] Container: DatatableComponent', () => { +// @Component({ selector: 'app-img', template: '' }) +// class ImgStubComponent { +// @Input() src: string; +// } +// +// @Component({ selector: 'app-thumbnail', template: '' }) +// class ThumbnailStubComponent { +// @Input() src: string; +// @Input() attributeName: string; +// } +// +// @Component({ selector: 'app-link', template: '' }) +// class LinkStubComponent { +// @Input() href: string; +// } +// +// @Component({ selector: 'app-btn', template: '' }) +// class BtnStubComponent { +// @Input() href: string; +// } +// +// @Component({ selector: 'app-detail', template: '' }) +// class DetailStubComponent { +// @Input() style: string; +// @Input() datasetName: string; +// @Input() data: string | number; +// } +// +// @Component({ selector: 'app-download', template: '' }) +// class DownloadStubComponent { +// @Input() href: string; +// } +// +// @Component({ selector: 'app-json-renderer', template: '' }) +// class JsonStubComponent { +// @Input() attributeName: string; +// @Input() json: string; +// } +// +// @Component({ selector: 'pagination', template: '' }) +// class PaginationStubComponent { +// @Input() totalItems: number; +// @Input() boundaryLinks: boolean; +// @Input() rotate: boolean; +// @Input() maxSize: number; +// } +// +// let component: DatatableComponent; +// let fixture: ComponentFixture; +// +// beforeEach(() => { +// TestBed.configureTestingModule({ +// declarations: [ +// DatatableComponent, +// ImgStubComponent, +// ThumbnailStubComponent, +// LinkStubComponent, +// BtnStubComponent, +// DetailStubComponent, +// DownloadStubComponent, +// JsonStubComponent, +// PaginationStubComponent +// ], +// imports: [AccordionModule.forRoot(), BrowserAnimationsModule] +// }); +// fixture = TestBed.createComponent(DatatableComponent); +// component = fixture.componentInstance; +// }); +// +// it('should create the component', () => { +// expect(component).toBeTruthy(); +// }); +// +// it('#requiredParams() should return if required params are loaded', () => { +// component.attributeList = ATTRIBUTE_LIST; +// component.outputList = [1]; +// component.dataLength = 1; +// expect(component.requiredParams()).toBeTruthy(); +// component.dataLength = undefined; +// expect(component.requiredParams()).toBeFalsy(); +// component.dataLength = 1; +// component.outputList = []; +// expect(component.requiredParams()).toBeFalsy(); +// component.outputList = [1]; +// component.attributeList = [] +// expect(component.requiredParams()).toBeFalsy(); +// }); +// +// it('#noSelectedData() should return true if no selectedData', () => { +// component.selectedData = []; +// expect(component.noSelectedData()).toBeTruthy(); +// }); +// +// it('#noSelectedData() should return false if there are selectedData', () => { +// component.selectedData = [123456]; +// expect(component.noSelectedData()).toBeFalsy(); +// }); +// +// it('#getOutputList() should return filtered output list', () => { +// component.outputList = [2] +// component.attributeList = ATTRIBUTE_LIST; +// expect(component.getOutputList().length).toBe(1); +// }); +// +// it('#toggleSelection(datum) should return add datum to selectedData', () => { +// const datum = { label_one: 123456 }; +// component.attributeList = ATTRIBUTE_LIST; +// component.selectedData = []; +// component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456)); +// component.toggleSelection(datum); +// }); +// +// it('#toggleSelection(datum) should return remove datum to selectedData', () => { +// const datum = { label_one: 123456 }; +// component.selectedData = [123456]; +// component.attributeList = ATTRIBUTE_LIST; +// component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456)); +// component.toggleSelection(datum); +// }); +// +// it('#isSelected(datum) should return true datum is selected', () => { +// const datum = { label_one: 123456 }; +// component.attributeList = ATTRIBUTE_LIST; +// component.selectedData = [123456]; +// expect(component.isSelected(datum)).toBeTruthy(); +// }); +// +// it('#isSelected(datum) should return false datum is not selected', () => { +// const datum = { label_one: 123456 }; +// component.attributeList = ATTRIBUTE_LIST; +// component.selectedData = []; +// expect(component.isSelected(datum)).toBeFalsy(); +// }); +// +// // it('#changePage() should change page value and raise getData event', () => { +// // component.dataset = DATASET; +// // component.sortedCol = 1; +// // component.sortedOrder = PaginationOrder.a; +// // const expectedPagination: Pagination = { +// // dname: 'cat_1', +// // page: 2, +// // nbItems: 10, +// // sortedCol: 1, +// // order: PaginationOrder.a +// // } +// // component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); +// // component.changePage(2); +// // }); +// +// it('#changeNbItems() should change nbItems value and raise getData event', () => { +// component.dataset = DATASET; +// component.sortedCol = 1; +// component.sortedOrder = PaginationOrder.a; +// const expectedPagination: Pagination = { +// dname: 'cat_1', +// page: 1, +// nbItems: 20, +// sortedCol: 1, +// order: PaginationOrder.a +// } +// component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); +// component.changeNbItems(20); +// }); +// +// it('#sort() should raise getData event with correct parameters', () => { +// component.dataset = DATASET; +// component.sortedOrder = PaginationOrder.a; +// let expectedPagination: Pagination = { +// dname: 'cat_1', +// page: 1, +// nbItems: 10, +// sortedCol: 1, +// order: PaginationOrder.a +// } +// let subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); +// component.sort(1); +// subscribtion.unsubscribe(); +// component.sortedCol = 1; +// component.sortedOrder = PaginationOrder.a; +// expectedPagination = { +// dname: 'cat_1', +// page: 1, +// nbItems: 10, +// sortedCol: 1, +// order: PaginationOrder.d +// } +// subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); +// component.sort(1); +// subscribtion.unsubscribe(); +// component.sortedCol = 1; +// component.sortedOrder = PaginationOrder.d; +// expectedPagination = { +// dname: 'cat_1', +// page: 1, +// nbItems: 10, +// sortedCol: 1, +// order: PaginationOrder.a +// } +// subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); +// component.sort(1); +// }); +// +// it('#ngOnInit() should init sortedCol value', () => { +// component.attributeList = ATTRIBUTE_LIST; +// component.ngOnInit(); +// expect(component.sortedCol).toEqual(1); +// }); +// }); +// diff --git a/src/app/shared/datatable/containers/datatable.component.ts b/src/app/shared/datatable/containers/datatable.component.ts index c93ffc2..cc93977 100644 --- a/src/app/shared/datatable/containers/datatable.component.ts +++ b/src/app/shared/datatable/containers/datatable.component.ts @@ -17,6 +17,7 @@ import { Pagination, PaginationOrder } from '../store/model'; import { Attribute, Dataset } from '../../../metamodel/model'; import { Observable } from 'rxjs'; import * as metamodelSelector from '../../../metamodel/selectors'; +import * as datatableActions from '../store/datatable.action'; /** * Interface for store state. @@ -136,14 +137,14 @@ export class DatatableComponent implements OnInit { } /** - * Emits event to change datatable page. + * Emits event to update datatable. * * @param {number} page - The datatable page number. * @param {number} nbItems - The items number to be displayed per page. * * @fires EventEmitter */ - changeDatatable(page: number, nbItems: number): void { + updateDatatable(page: number, nbItems: number): void { const pagination: Pagination = { dname: this.dataset.name, page: page, @@ -152,64 +153,8 @@ export class DatatableComponent implements OnInit { order: PaginationOrder.a }; this.getData.emit(pagination); - } - - /** - * Emits event to change datatable page. - * - * @param {number} page - The page number to access. - * - * @fires EventEmitter - */ - // changePage(page: number): void { - // this.nbItems.subscribe(nb => { - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: page, - // nbItems: nb, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); - // }); - // this.page = nb; - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: page, - // nbItems: this.nbItems, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); - // } - - /** - * Emits event to change datatable displayed items. - * - * @param {number} nbItems - The number of items to display. - * - * @fires EventEmitter - */ - changeNbItems(nbItems: number): void { - this.page.subscribe(p => { - const pagination: Pagination = { - dname: this.dataset.name, - page: p, - nbItems: nbItems, - sortedCol: this.sortedCol, - order: PaginationOrder.a - }; - this.getData.emit(pagination); - }); - // this.nbItems = nb; - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: this.page, - // nbItems: this.nbItems, - // sortedCol: this.sortedCol, - // order: PaginationOrder.a - // }; - // this.getData.emit(pagination); + this.store.dispatch(new datatableActions.ChangePageAction(page)); + this.store.dispatch(new datatableActions.ChangeNbItemsAction(nbItems)); } /** diff --git a/src/app/shared/datatable/index.ts b/src/app/shared/datatable/index.ts index 7a8e43b..8b36006 100644 --- a/src/app/shared/datatable/index.ts +++ b/src/app/shared/datatable/index.ts @@ -1,9 +1,11 @@ import { DatatableComponent } from './containers/datatable.component'; import { TablePaginationComponent } from './components/table-pagination.component'; +import { TableNbItemsComponent } from './components/table-nb-items.component'; import { rendererComponents } from './components/renderer'; export const datatableComponents = [ DatatableComponent, TablePaginationComponent, + TableNbItemsComponent, rendererComponents ]; diff --git a/src/app/shared/datatable/store/datatable.reducer.ts b/src/app/shared/datatable/store/datatable.reducer.ts index ab9c3da..73f610b 100644 --- a/src/app/shared/datatable/store/datatable.reducer.ts +++ b/src/app/shared/datatable/store/datatable.reducer.ts @@ -36,42 +36,17 @@ export const initialState: State = { */ export function reducer(state: State = initialState, action: actions.Actions): State { switch (action.type) { - // case actions.RETRIEVE_COORDINATES: - // return { - // ...state, - // resolverWip: true - // }; - // - // case actions.RETRIEVE_COORDINATES_SUCCESS: - // return { - // ...state, - // resolverWip: false, - // resolver: action.payload - // }; - // - // case actions.RETRIEVE_COORDINATES_FAIL: - // return { - // ...state, - // resolverWip: false - // }; - // - // case actions.DELETE_RESOLVER: - // return { - // ...state, - // resolver: null - // }; - // - // case actions.ADD_CONE_SEARCH: - // return { - // ...state, - // coneSearch: action.payload - // }; - // - // case actions.DELETE_CONE_SEARCH: - // return { - // ...state, - // coneSearch: { ra: null, dec: null, radius: null } - // }; + case actions.CHANGE_PAGE: + return { + ...state, + page: action.payload + }; + + case actions.CHANGE_NB_ITEMS: + return { + ...state, + nbItems: action.payload + }; default: return state; -- GitLab From 8749db539e7a3d5c68e1c0ed873edb574997b5d1 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Fri, 22 Jan 2021 16:31:15 +0100 Subject: [PATCH 09/16] WIP: Save sort options to the store --- .../containers/datatable.component.html | 23 +- .../datatable/store/datatable.action.spec.ts | 15 ++ .../datatable/store/datatable.action.ts | 27 +++ .../datatable/store/datatable.reducer.spec.ts | 210 +++++++++--------- .../datatable/store/datatable.reducer.ts | 19 ++ .../store/datatable.selector.spec.ts | 10 + .../datatable/store/datatable.selector.ts | 10 + 7 files changed, 184 insertions(+), 130 deletions(-) diff --git a/src/app/shared/datatable/containers/datatable.component.html b/src/app/shared/datatable/containers/datatable.component.html index d316274..ea02056 100644 --- a/src/app/shared/datatable/containers/datatable.component.html +++ b/src/app/shared/datatable/containers/datatable.component.html @@ -104,18 +104,10 @@
+ [dataLength]="dataLength" + [page]="page | async" + (changeTableNbItems)="updateDatatable($event.page, $event.nbItems)"> - - - - - - - -
- - - - - - - - -
\ No newline at end of file diff --git a/src/app/shared/datatable/store/datatable.action.spec.ts b/src/app/shared/datatable/store/datatable.action.spec.ts index 77e94e2..476f945 100644 --- a/src/app/shared/datatable/store/datatable.action.spec.ts +++ b/src/app/shared/datatable/store/datatable.action.spec.ts @@ -1,4 +1,5 @@ import * as datatableActions from '../store/datatable.action'; +import { PaginationOrder } from './model'; describe('[Shared][Datatable] Action', () => { it('should create ChangePageAction', () => { @@ -13,11 +14,25 @@ describe('[Shared][Datatable] Action', () => { expect(action.payload).toEqual(2); }); + it('should create ChangeSortedColAction', () => { + const action = new datatableActions.ChangeSortedColAction(2); + expect(action.type).toEqual(datatableActions.CHANGE_SORTED_COL); + expect(action.payload).toEqual(2); + }); + + it('should create ChangeSortedOrderAction', () => { + const order: PaginationOrder = PaginationOrder.a; + const action = new datatableActions.ChangeSortedOrderAction(order); + expect(action.type).toEqual(datatableActions.CHANGE_SORTED_ORDER); + expect(action.payload).toEqual('a'); + }); + it('should create AddVisitedAction', () => { const action = new datatableActions.AddVisitedAction(2); expect(action.type).toEqual(datatableActions.ADD_VISITED); expect(action.payload).toEqual(2); }); + it('should create ResetDatatableAction', () => { const action = new datatableActions.ResetDatatableAction(); expect(action.type).toEqual(datatableActions.RESET_DATATABLE); diff --git a/src/app/shared/datatable/store/datatable.action.ts b/src/app/shared/datatable/store/datatable.action.ts index 02c7ffa..2dc8639 100644 --- a/src/app/shared/datatable/store/datatable.action.ts +++ b/src/app/shared/datatable/store/datatable.action.ts @@ -8,9 +8,12 @@ */ import { Action } from '@ngrx/store'; +import { PaginationOrder } from './model'; export const CHANGE_PAGE = '[Datatable] Change Page'; export const CHANGE_NB_ITEMS = '[Datatable] Change Nb Items'; +export const CHANGE_SORTED_COL = '[Datatable] Change Sorted Col'; +export const CHANGE_SORTED_ORDER = '[Datatable] Change Sorted Order'; export const ADD_VISITED = '[Datatable] Add Visited'; export const RESET_DATATABLE = '[Datatable] Reset Datatable'; @@ -37,6 +40,28 @@ export class ChangeNbItemsAction implements Action { constructor(public payload: number) { } } +/** + * @class + * @classdesc ChangeSortedOrderAction action. + * @readonly + */ +export class ChangeSortedOrderAction implements Action { + readonly type = CHANGE_SORTED_ORDER; + + constructor(public payload: PaginationOrder) { } +} + +/** + * @class + * @classdesc ChangeSortedColAction action. + * @readonly + */ +export class ChangeSortedColAction implements Action { + readonly type = CHANGE_SORTED_COL; + + constructor(public payload: number) { } +} + /** * @class * @classdesc AddVisitedAction action. @@ -62,5 +87,7 @@ export class ResetDatatableAction implements Action { export type Actions = ChangePageAction | ChangeNbItemsAction + | ChangeSortedColAction + | ChangeSortedOrderAction | AddVisitedAction | ResetDatatableAction; diff --git a/src/app/shared/datatable/store/datatable.reducer.spec.ts b/src/app/shared/datatable/store/datatable.reducer.spec.ts index 2eca75d..f6788f5 100644 --- a/src/app/shared/datatable/store/datatable.reducer.spec.ts +++ b/src/app/shared/datatable/store/datatable.reducer.spec.ts @@ -1,5 +1,6 @@ import * as fromDatatable from './datatable.reducer'; import * as datatableActions from './datatable.action'; +import { PaginationOrder } from './model'; describe('[Shared][Datatable] Reducer', () => { it('should return init state', () => { @@ -10,116 +11,105 @@ describe('[Shared][Datatable] Reducer', () => { expect(state).toBe(initialState); }); - // it('should set resolverWip to true', () => { - // const { initialState } = fromConeSearch; - // const action = new coneSearchActions.RetrieveCoordinatesAction('toto'); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeTruthy(); - // expect(state.resolver).toBeNull(); - // expect(state.coneSearch.ra).toBeNull(); - // expect(state.coneSearch.dec).toBeNull(); - // expect(state.coneSearch.radius).toBeNull(); - // expect(state).not.toEqual(initialState); - // }); - // - // it('should set resolver ans resolverWip to false', () => { - // const resolver: Resolver = { name: 'toto', ra: 1, dec: 2 }; - // const initialState = { - // ...fromConeSearch.initialState, - // resolverWip: true - // }; - // const action = new coneSearchActions.RetrieveCoordinatesSuccessAction(resolver); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeFalsy(); - // expect(state.resolver).toEqual(resolver); - // expect(state.coneSearch.ra).toBeNull(); - // expect(state.coneSearch.dec).toBeNull(); - // expect(state.coneSearch.radius).toBeNull(); - // expect(state).not.toEqual(initialState); - // }); - // - // it('should set resolverWip to false', () => { - // const initialState = { - // ...fromConeSearch.initialState, - // resolverWip: true - // }; - // const action = new coneSearchActions.RetrieveCoordinatesFailAction(null); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeFalsy(); - // expect(state.resolver).toBeNull(); - // expect(state.coneSearch.ra).toBeNull(); - // expect(state.coneSearch.dec).toBeNull(); - // expect(state.coneSearch.radius).toBeNull(); - // expect(state).not.toEqual(initialState); - // }); - // - // it('should unset resolver', () => { - // const resolver: Resolver = { name: 'toto', ra: 1, dec: 2 }; - // const initialState = { - // ...fromConeSearch.initialState, - // resolver - // }; - // const action = new coneSearchActions.DeleteResolverAction(); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeFalsy(); - // expect(state.resolver).toBeNull(); - // expect(state.coneSearch.ra).toBeNull(); - // expect(state.coneSearch.dec).toBeNull(); - // expect(state.coneSearch.radius).toBeNull(); - // expect(state).not.toEqual(initialState); - // }); - // - // it('should set coneSearch', () => { - // const coneSearch = { ra: 1, dec: 2, radius: 3 } as ConeSearch; - // const { initialState } = fromConeSearch; - // const action = new coneSearchActions.AddConeSearchAction(coneSearch); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeFalsy(); - // expect(state.resolver).toBeNull(); - // expect(state.coneSearch.ra).toEqual(1); - // expect(state.coneSearch.dec).toEqual(2); - // expect(state.coneSearch.radius).toEqual(3); - // expect(state).not.toEqual(initialState); - // }); - // - // it('should unset coneSearch', () => { - // const coneSearch = { ra: 1, dec: 2, radius: 3 } as ConeSearch; - // const initialState = { ...fromConeSearch.initialState, coneSearch }; - // const action = new coneSearchActions.DeleteConeSearchAction(); - // const state = fromConeSearch.reducer(initialState, action); - // - // expect(state.resolverWip).toBeFalsy(); - // expect(state.resolver).toBeNull(); - // expect(state.coneSearch.ra).toBeNull(); - // expect(state.coneSearch.dec).toBeNull(); - // expect(state.coneSearch.radius).toBeNull(); + it('should update page', () => { + const { initialState } = fromDatatable; + const action = new datatableActions.ChangePageAction(2); + const state = fromDatatable.reducer(initialState, action); + + expect(state.page).toEqual(2); + expect(state.nbItems).toEqual(10); + expect(state.sortedCol).toBeNull(); + expect(state.sortedOrder).toEqual('a'); + expect(state.visited.length).toEqual(0); + expect(state).not.toEqual(initialState); + }); + + it('should update nbItems', () => { + const { initialState } = fromDatatable; + const action = new datatableActions.ChangeNbItemsAction(20); + const state = fromDatatable.reducer(initialState, action); + + expect(state.page).toEqual(1); + expect(state.nbItems).toEqual(20); + expect(state.sortedCol).toBeNull(); + expect(state.sortedOrder).toEqual('a'); + expect(state.visited.length).toEqual(0); + expect(state).not.toEqual(initialState); + }); + + it('should update sortedCol', () => { + const { initialState } = fromDatatable; + const action = new datatableActions.ChangeSortedColAction(1); + const state = fromDatatable.reducer(initialState, action); + + expect(state.page).toEqual(1); + expect(state.nbItems).toEqual(10); + expect(state.sortedCol).toEqual(1); + expect(state.sortedOrder).toEqual('a'); + expect(state.visited.length).toEqual(0); + expect(state).not.toEqual(initialState); + }); + + it('should update sortedOrder', () => { + const order: PaginationOrder = PaginationOrder.d; + const { initialState } = fromDatatable; + const action = new datatableActions.ChangeSortedOrderAction(order); + const state = fromDatatable.reducer(initialState, action); + + expect(state.page).toEqual(1); + expect(state.nbItems).toEqual(10); + expect(state.sortedCol).toBeNull(); + expect(state.sortedOrder).toEqual('d'); + expect(state.visited.length).toEqual(0); + expect(state).not.toEqual(initialState); + }); + + // it('should update visited', () => { + // const { initialState } = fromDatatable; + // const action = new datatableActions.AddVisitedAction(1); + // const state = fromDatatable.reducer(initialState, action); + // + // expect(state.page).toEqual(1); + // expect(state.nbItems).toEqual(10); + // expect(state.sortedCol).toBeNull(); + // expect(state.sortedOrder).toEqual('a'); + // expect(state.visited.length).toEqual(1); + // expect(state.visited).toEqual([1]); // expect(state).not.toEqual(initialState); // }); - // - // it('should get resolverWip', () => { - // const action = {} as coneSearchActions.Actions; - // const state = fromConeSearch.reducer(undefined, action); - // - // expect(fromConeSearch.getResolverWip(state)).toBeFalsy(); - // }); - // - // it('should get resolver', () => { - // const action = {} as coneSearchActions.Actions; - // const state = fromConeSearch.reducer(undefined, action); - // - // expect(fromConeSearch.getResolver(state)).toBeNull(); - // }); - // - // it('should get coneSearch', () => { - // const action = {} as coneSearchActions.Actions; - // const state = fromConeSearch.reducer(undefined, action); - // const expectedConeSearch: ConeSearch = { ra: null, dec: null, radius: null }; - // - // expect(fromConeSearch.getConeSearch(state)).toEqual(expectedConeSearch); - // }); + + it('should get page', () => { + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(fromDatatable.getPage(state)).toEqual(1); + }); + + it('should get nbItems', () => { + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(fromDatatable.getNbItems(state)).toEqual(10); + }); + + it('should get sortedCol', () => { + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(fromDatatable.getSortedCol(state)).toBeNull(); + }); + + it('should get sortedOrder', () => { + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(fromDatatable.getSortedOrder(state)).toEqual('a'); + }); + + it('should get visited', () => { + const action = {} as datatableActions.Actions; + const state = fromDatatable.reducer(undefined, action); + + expect(fromDatatable.getVisited(state).length).toEqual(0); + }); }); diff --git a/src/app/shared/datatable/store/datatable.reducer.ts b/src/app/shared/datatable/store/datatable.reducer.ts index 73f610b..df4e3f4 100644 --- a/src/app/shared/datatable/store/datatable.reducer.ts +++ b/src/app/shared/datatable/store/datatable.reducer.ts @@ -8,6 +8,7 @@ */ import * as actions from './datatable.action'; +import { PaginationOrder } from './model'; /** * Interface for datatable state. @@ -17,12 +18,16 @@ import * as actions from './datatable.action'; export interface State { page: number; nbItems: number; + sortedCol: number; + sortedOrder: PaginationOrder; visited: number[]; } export const initialState: State = { page: 1, nbItems: 10, + sortedCol: null, + sortedOrder: PaginationOrder.a, visited: [] }; @@ -48,6 +53,18 @@ export function reducer(state: State = initialState, action: actions.Actions): S nbItems: action.payload }; + case actions.CHANGE_SORTED_COL: + return { + ...state, + sortedCol: action.payload + }; + + case actions.CHANGE_SORTED_ORDER: + return { + ...state, + sortedOrder: action.payload + }; + default: return state; } @@ -55,4 +72,6 @@ export function reducer(state: State = initialState, action: actions.Actions): S export const getPage = (state: State) => state.page; export const getNbItems = (state: State) => state.nbItems; +export const getSortedCol = (state: State) => state.sortedCol; +export const getSortedOrder = (state: State) => state.sortedOrder; export const getVisited = (state: State) => state.visited; diff --git a/src/app/shared/datatable/store/datatable.selector.spec.ts b/src/app/shared/datatable/store/datatable.selector.spec.ts index 1e057dd..3dbaf41 100644 --- a/src/app/shared/datatable/store/datatable.selector.spec.ts +++ b/src/app/shared/datatable/store/datatable.selector.spec.ts @@ -12,6 +12,16 @@ describe('[Shared][Datatable] Selector', () => { expect(datatableSelector.getNbItems(state)).toEqual(10); }); + it('should get sortedCol', () => { + const state = { datatable: { ...fromDatatable.initialState }}; + expect(datatableSelector.getSortedCol(state)).toBeNull(); + }); + + it('should get sortedOrder', () => { + const state = { datatable: { ...fromDatatable.initialState }}; + expect(datatableSelector.getSortedOrder(state)).toEqual('a'); + }); + it('should get visited', () => { const state = { datatable: { ...fromDatatable.initialState }}; expect(datatableSelector.getVisited(state).length).toEqual(0); diff --git a/src/app/shared/datatable/store/datatable.selector.ts b/src/app/shared/datatable/store/datatable.selector.ts index df59dcc..2082f6b 100644 --- a/src/app/shared/datatable/store/datatable.selector.ts +++ b/src/app/shared/datatable/store/datatable.selector.ts @@ -23,6 +23,16 @@ export const getNbItems = createSelector( datatable.getNbItems ); +export const getSortedCol = createSelector( + getDatatableState, + datatable.getSortedCol +); + +export const getSortedOrder = createSelector( + getDatatableState, + datatable.getSortedOrder +); + export const getVisited = createSelector( getDatatableState, datatable.getVisited -- GitLab From 6b8692f364581c23c1e2a0863c30138d49370e9e Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Thu, 28 Jan 2021 17:10:21 +0100 Subject: [PATCH 10/16] Save sortedCol and sortedOrder to store => DONE --- .../containers/datatable.component.html | 8 +- .../containers/datatable.component.ts | 88 ++++++++++++++----- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/app/shared/datatable/containers/datatable.component.html b/src/app/shared/datatable/containers/datatable.component.html index ea02056..ac4a466 100644 --- a/src/app/shared/datatable/containers/datatable.component.html +++ b/src/app/shared/datatable/containers/datatable.component.html @@ -23,15 +23,15 @@ {{ attribute.label }} - - + + - + - + diff --git a/src/app/shared/datatable/containers/datatable.component.ts b/src/app/shared/datatable/containers/datatable.component.ts index cc93977..0c8a243 100644 --- a/src/app/shared/datatable/containers/datatable.component.ts +++ b/src/app/shared/datatable/containers/datatable.component.ts @@ -10,14 +10,13 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; import * as fromDatatable from '../store/datatable.reducer'; +import * as datatableActions from '../store/datatable.action'; import * as datatableSelector from '../store/datatable.selector'; import { Pagination, PaginationOrder } from '../store/model'; import { Attribute, Dataset } from '../../../metamodel/model'; -import { Observable } from 'rxjs'; -import * as metamodelSelector from '../../../metamodel/selectors'; -import * as datatableActions from '../store/datatable.action'; /** * Interface for store state. @@ -56,19 +55,21 @@ export class DatatableComponent implements OnInit { page: Observable; nbItems: Observable; + sortedCol: Observable; + sortedOrder: Observable; visited: Observable; - sortedCol: number = null; - sortedOrder: PaginationOrder = PaginationOrder.a; - constructor(private store: Store) { this.page = store.select(datatableSelector.getPage); this.nbItems = store.select(datatableSelector.getNbItems); + this.sortedCol = store.select(datatableSelector.getSortedCol); + this.sortedOrder = store.select(datatableSelector.getSortedOrder); this.visited = store.select(datatableSelector.getVisited); } ngOnInit() { - this.sortedCol = this.attributeList.find(a => a.search_flag === 'ID').id; + const defaultSortedCol = this.attributeList.find(a => a.search_flag === 'ID').id; + this.store.dispatch(new datatableActions.ChangeSortedColAction(defaultSortedCol)); } /** @@ -77,7 +78,7 @@ export class DatatableComponent implements OnInit { * @return boolean */ requiredParams(): boolean { - if (this.attributeList.length === 0 || this.outputList.length === 0 || !this.dataLength) { + if (this.attributeList.length === 0 || this.outputList.length === 0 || !this.dataLength || !this.getSortedCol()) { return false; } return true; @@ -149,7 +150,7 @@ export class DatatableComponent implements OnInit { dname: this.dataset.name, page: page, nbItems: nbItems, - sortedCol: this.sortedCol, + sortedCol: this.getSortedCol(), order: PaginationOrder.a }; this.getData.emit(pagination); @@ -165,19 +166,64 @@ export class DatatableComponent implements OnInit { * @fires EventEmitter */ sort(id: number): void { - if (id === this.sortedCol) { - this.sortedOrder = this.sortedOrder === PaginationOrder.a ? PaginationOrder.d : PaginationOrder.a; + let order: PaginationOrder = PaginationOrder.a; + if (id === this.getSortedCol()) { + order = this.getSortedOrder() === PaginationOrder.a ? PaginationOrder.d : PaginationOrder.a; } else { - this.sortedCol = id; - this.sortedOrder = PaginationOrder.a; + this.store.dispatch(new datatableActions.ChangeSortedColAction(id)); } - // const pagination: Pagination = { - // dname: this.dataset.name, - // page: this.page, - // nbItems: this.nbItems, - // sortedCol: this.sortedCol, - // order: this.sortedOrder - // }; - // this.getData.emit(pagination); + this.store.dispatch(new datatableActions.ChangeSortedOrderAction(order)); + const pagination: Pagination = { + dname: this.dataset.name, + page: this.getPage(), + nbItems: this.getNbItems(), + sortedCol: this.getSortedCol(), + order: this.getSortedOrder() + }; + this.getData.emit(pagination); + } + + /** + * Returns page. + * + * @return number + */ + getPage(): number { + let page: number; + this.page.subscribe(p => page = p); + return page; + } + + /** + * Returns nbItems. + * + * @return number + */ + getNbItems(): number { + let nbItems: number; + this.nbItems.subscribe(nb => nbItems = nb); + return nbItems; + } + + /** + * Returns sortedCol. + * + * @return number + */ + getSortedCol(): number { + let sortedCol: number; + this.sortedCol.subscribe(col => sortedCol = col); + return sortedCol; + } + + /** + * Returns sortedOrder. + * + * @return PaginationOrder + */ + getSortedOrder(): PaginationOrder { + let sortedOrder: PaginationOrder; + this.sortedOrder.subscribe(order => sortedOrder = order); + return sortedOrder; } } -- GitLab From d6e70b75cbf2802fc374426eb804a0044e17c621 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Fri, 29 Jan 2021 17:08:26 +0100 Subject: [PATCH 11/16] Tests on containers => DONE, Refactoring file structure => DONE --- .../{renderer => }/detail.component.html | 2 +- .../{renderer => }/detail.component.spec.ts | 2 +- .../{renderer => }/detail.component.ts | 2 +- .../components/download.component.html | 4 + .../{renderer => }/download.component.spec.ts | 4 +- .../{renderer => }/download.component.ts | 4 +- .../{renderer => }/image.component.html | 0 .../{renderer => }/image.component.spec.ts | 4 +- .../{renderer => }/image.component.ts | 4 +- .../{renderer => }/json.component.html | 4 +- .../{renderer => }/json.component.spec.ts | 2 +- .../{renderer => }/json.component.ts | 3 +- .../datatable/components/link.component.html | 5 + .../{renderer => }/link.component.spec.ts | 2 +- .../{renderer => }/link.component.ts | 2 +- .../renderer/download.component.html | 4 - .../datatable/components/renderer/index.ts | 13 - .../components/renderer/link.component.html | 5 - .../components/table-nb-items.component.css | 12 - .../components/table-nb-items.component.html | 8 - .../table-nb-items.component.spec.ts | 21 - .../components/table-nb-items.component.ts | 25 - .../table-pagination.component.html | 10 - .../table-pagination.component.spec.ts | 33 -- .../components/table-pagination.component.ts | 28 - .../containers/datatable.component.css | 4 + .../containers/datatable.component.html | 27 +- .../containers/datatable.component.spec.ts | 479 ++++++++++-------- .../containers/datatable.component.ts | 134 ++--- src/app/shared/datatable/index.ts | 16 +- 30 files changed, 386 insertions(+), 477 deletions(-) rename src/app/shared/datatable/components/{renderer => }/detail.component.html (59%) rename src/app/shared/datatable/components/{renderer => }/detail.component.spec.ts (89%) rename src/app/shared/datatable/components/{renderer => }/detail.component.ts (93%) create mode 100644 src/app/shared/datatable/components/download.component.html rename src/app/shared/datatable/components/{renderer => }/download.component.spec.ts (83%) rename src/app/shared/datatable/components/{renderer => }/download.component.ts (91%) rename src/app/shared/datatable/components/{renderer => }/image.component.html (100%) rename src/app/shared/datatable/components/{renderer => }/image.component.spec.ts (84%) rename src/app/shared/datatable/components/{renderer => }/image.component.ts (91%) rename src/app/shared/datatable/components/{renderer => }/json.component.html (91%) rename src/app/shared/datatable/components/{renderer => }/json.component.spec.ts (91%) rename src/app/shared/datatable/components/{renderer => }/json.component.ts (95%) create mode 100644 src/app/shared/datatable/components/link.component.html rename src/app/shared/datatable/components/{renderer => }/link.component.spec.ts (94%) rename src/app/shared/datatable/components/{renderer => }/link.component.ts (95%) delete mode 100644 src/app/shared/datatable/components/renderer/download.component.html delete mode 100644 src/app/shared/datatable/components/renderer/index.ts delete mode 100644 src/app/shared/datatable/components/renderer/link.component.html delete mode 100644 src/app/shared/datatable/components/table-nb-items.component.css delete mode 100644 src/app/shared/datatable/components/table-nb-items.component.html delete mode 100644 src/app/shared/datatable/components/table-nb-items.component.spec.ts delete mode 100644 src/app/shared/datatable/components/table-nb-items.component.ts delete mode 100644 src/app/shared/datatable/components/table-pagination.component.html delete mode 100644 src/app/shared/datatable/components/table-pagination.component.spec.ts delete mode 100644 src/app/shared/datatable/components/table-pagination.component.ts diff --git a/src/app/shared/datatable/components/renderer/detail.component.html b/src/app/shared/datatable/components/detail.component.html similarity index 59% rename from src/app/shared/datatable/components/renderer/detail.component.html rename to src/app/shared/datatable/components/detail.component.html index 0b6336b..9fd2771 100644 --- a/src/app/shared/datatable/components/renderer/detail.component.html +++ b/src/app/shared/datatable/components/detail.component.html @@ -1,4 +1,4 @@ + [ngClass]="{ 'btn btn-outline-primary btn-sm' : config.display == 'text-button' }"> {{ value }} diff --git a/src/app/shared/datatable/components/renderer/detail.component.spec.ts b/src/app/shared/datatable/components/detail.component.spec.ts similarity index 89% rename from src/app/shared/datatable/components/renderer/detail.component.spec.ts rename to src/app/shared/datatable/components/detail.component.spec.ts index 1f12638..b959bae 100644 --- a/src/app/shared/datatable/components/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('[Shared][Datatable][Renderer] Component: DetailComponent', () => { +describe('[Shared][Datatable] Component: DetailComponent', () => { let component: DetailComponent; let fixture: ComponentFixture; diff --git a/src/app/shared/datatable/components/renderer/detail.component.ts b/src/app/shared/datatable/components/detail.component.ts similarity index 93% rename from src/app/shared/datatable/components/renderer/detail.component.ts rename to src/app/shared/datatable/components/detail.component.ts index 7f583ff..2bbcc88 100644 --- a/src/app/shared/datatable/components/renderer/detail.component.ts +++ b/src/app/shared/datatable/components/detail.component.ts @@ -9,7 +9,7 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; -import { RendererConfig } from "../../../../metamodel/model"; +import { RendererConfig } from '../../../metamodel/model'; /** * Interface for detail renderer configuration. 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 0000000..1094349 --- /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/components/renderer/download.component.spec.ts b/src/app/shared/datatable/components/download.component.spec.ts similarity index 83% rename from src/app/shared/datatable/components/renderer/download.component.spec.ts rename to src/app/shared/datatable/components/download.component.spec.ts index 63370b9..4d34eef 100644 --- a/src/app/shared/datatable/components/renderer/download.component.spec.ts +++ b/src/app/shared/datatable/components/download.component.spec.ts @@ -1,9 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { DownloadComponent } from './download.component'; -import { environment } from '../../../../../environments/environment'; +import { environment } from '../../../../environments/environment'; -describe('[Shared][Datatable][Renderer] Component: DownloadComponent', () => { +describe('[Shared][Datatable] Component: DownloadComponent', () => { let component: DownloadComponent; let fixture: ComponentFixture; diff --git a/src/app/shared/datatable/components/renderer/download.component.ts b/src/app/shared/datatable/components/download.component.ts similarity index 91% rename from src/app/shared/datatable/components/renderer/download.component.ts rename to src/app/shared/datatable/components/download.component.ts index 4b1d5a2..eec94cf 100644 --- a/src/app/shared/datatable/components/renderer/download.component.ts +++ b/src/app/shared/datatable/components/download.component.ts @@ -9,8 +9,8 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; -import { RendererConfig } from '../../../../metamodel/model'; -import { getHost } from "../../../utils"; +import { RendererConfig } from '../../../metamodel/model'; +import { getHost } from '../../utils'; /** * Interface for download renderer configuration. diff --git a/src/app/shared/datatable/components/renderer/image.component.html b/src/app/shared/datatable/components/image.component.html similarity index 100% rename from src/app/shared/datatable/components/renderer/image.component.html rename to src/app/shared/datatable/components/image.component.html diff --git a/src/app/shared/datatable/components/renderer/image.component.spec.ts b/src/app/shared/datatable/components/image.component.spec.ts similarity index 84% rename from src/app/shared/datatable/components/renderer/image.component.spec.ts rename to src/app/shared/datatable/components/image.component.spec.ts index d505d01..ad91235 100644 --- a/src/app/shared/datatable/components/renderer/image.component.spec.ts +++ b/src/app/shared/datatable/components/image.component.spec.ts @@ -1,9 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ImageComponent } from './image.component'; -import { environment } from '../../../../../environments/environment'; +import { environment } from '../../../../environments/environment'; -describe('[Shared][Datatable][Renderer] Component: ImageComponent', () => { +describe('[Shared][Datatable] Component: ImageComponent', () => { let component: ImageComponent; let fixture: ComponentFixture; diff --git a/src/app/shared/datatable/components/renderer/image.component.ts b/src/app/shared/datatable/components/image.component.ts similarity index 91% rename from src/app/shared/datatable/components/renderer/image.component.ts rename to src/app/shared/datatable/components/image.component.ts index 2879269..eb44057 100644 --- a/src/app/shared/datatable/components/renderer/image.component.ts +++ b/src/app/shared/datatable/components/image.component.ts @@ -9,8 +9,8 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; -import { RendererConfig } from '../../../../metamodel/model'; -import { getHost } from "../../../utils"; +import { RendererConfig } from '../../../metamodel/model'; +import { getHost } from '../../utils'; /** * Interface for image renderer configuration. diff --git a/src/app/shared/datatable/components/renderer/json.component.html b/src/app/shared/datatable/components/json.component.html similarity index 91% rename from src/app/shared/datatable/components/renderer/json.component.html rename to src/app/shared/datatable/components/json.component.html index 95f6bf5..82d6886 100644 --- a/src/app/shared/datatable/components/renderer/json.component.html +++ b/src/app/shared/datatable/components/json.component.html @@ -1,6 +1,4 @@ - +
- - + Showing + + of {{ dataLength }} items
- - + +
\ No newline at end of file diff --git a/src/app/shared/datatable/containers/datatable.component.spec.ts b/src/app/shared/datatable/containers/datatable.component.spec.ts index a1e8dab..a0306ff 100644 --- a/src/app/shared/datatable/containers/datatable.component.spec.ts +++ b/src/app/shared/datatable/containers/datatable.component.spec.ts @@ -1,220 +1,259 @@ -// import { ComponentFixture, TestBed } from '@angular/core/testing'; -// import { Component, Input } from '@angular/core'; -// import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -// -// import { AccordionModule } from 'ngx-bootstrap/accordion'; -// -// import { DatatableComponent } from './datatable.component'; -// import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; -// import { Pagination, PaginationOrder } from '../store/model'; -// -// describe('[Shared][Datatable] Container: DatatableComponent', () => { -// @Component({ selector: 'app-img', template: '' }) -// class ImgStubComponent { -// @Input() src: string; -// } -// -// @Component({ selector: 'app-thumbnail', template: '' }) -// class ThumbnailStubComponent { -// @Input() src: string; -// @Input() attributeName: string; -// } -// -// @Component({ selector: 'app-link', template: '' }) -// class LinkStubComponent { -// @Input() href: string; -// } -// -// @Component({ selector: 'app-btn', template: '' }) -// class BtnStubComponent { -// @Input() href: string; -// } -// -// @Component({ selector: 'app-detail', template: '' }) -// class DetailStubComponent { -// @Input() style: string; -// @Input() datasetName: string; -// @Input() data: string | number; -// } -// -// @Component({ selector: 'app-download', template: '' }) -// class DownloadStubComponent { -// @Input() href: string; -// } -// -// @Component({ selector: 'app-json-renderer', template: '' }) -// class JsonStubComponent { -// @Input() attributeName: string; -// @Input() json: string; -// } -// -// @Component({ selector: 'pagination', template: '' }) -// class PaginationStubComponent { -// @Input() totalItems: number; -// @Input() boundaryLinks: boolean; -// @Input() rotate: boolean; -// @Input() maxSize: number; -// } -// -// let component: DatatableComponent; -// let fixture: ComponentFixture; -// -// beforeEach(() => { -// TestBed.configureTestingModule({ -// declarations: [ -// DatatableComponent, -// ImgStubComponent, -// ThumbnailStubComponent, -// LinkStubComponent, -// BtnStubComponent, -// DetailStubComponent, -// DownloadStubComponent, -// JsonStubComponent, -// PaginationStubComponent -// ], -// imports: [AccordionModule.forRoot(), BrowserAnimationsModule] -// }); -// fixture = TestBed.createComponent(DatatableComponent); -// component = fixture.componentInstance; -// }); -// -// it('should create the component', () => { -// expect(component).toBeTruthy(); -// }); -// -// it('#requiredParams() should return if required params are loaded', () => { -// component.attributeList = ATTRIBUTE_LIST; -// component.outputList = [1]; -// component.dataLength = 1; -// expect(component.requiredParams()).toBeTruthy(); -// component.dataLength = undefined; -// expect(component.requiredParams()).toBeFalsy(); -// component.dataLength = 1; -// component.outputList = []; -// expect(component.requiredParams()).toBeFalsy(); -// component.outputList = [1]; -// component.attributeList = [] -// expect(component.requiredParams()).toBeFalsy(); -// }); -// -// it('#noSelectedData() should return true if no selectedData', () => { -// component.selectedData = []; -// expect(component.noSelectedData()).toBeTruthy(); -// }); -// -// it('#noSelectedData() should return false if there are selectedData', () => { -// component.selectedData = [123456]; -// expect(component.noSelectedData()).toBeFalsy(); -// }); -// -// it('#getOutputList() should return filtered output list', () => { -// component.outputList = [2] -// component.attributeList = ATTRIBUTE_LIST; -// expect(component.getOutputList().length).toBe(1); -// }); -// -// it('#toggleSelection(datum) should return add datum to selectedData', () => { -// const datum = { label_one: 123456 }; -// component.attributeList = ATTRIBUTE_LIST; -// component.selectedData = []; -// component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456)); -// component.toggleSelection(datum); -// }); -// -// it('#toggleSelection(datum) should return remove datum to selectedData', () => { -// const datum = { label_one: 123456 }; -// component.selectedData = [123456]; -// component.attributeList = ATTRIBUTE_LIST; -// component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456)); -// component.toggleSelection(datum); -// }); -// -// it('#isSelected(datum) should return true datum is selected', () => { -// const datum = { label_one: 123456 }; -// component.attributeList = ATTRIBUTE_LIST; -// component.selectedData = [123456]; -// expect(component.isSelected(datum)).toBeTruthy(); -// }); -// -// it('#isSelected(datum) should return false datum is not selected', () => { -// const datum = { label_one: 123456 }; -// component.attributeList = ATTRIBUTE_LIST; -// component.selectedData = []; -// expect(component.isSelected(datum)).toBeFalsy(); -// }); -// -// // it('#changePage() should change page value and raise getData event', () => { -// // component.dataset = DATASET; -// // component.sortedCol = 1; -// // component.sortedOrder = PaginationOrder.a; -// // const expectedPagination: Pagination = { -// // dname: 'cat_1', -// // page: 2, -// // nbItems: 10, -// // sortedCol: 1, -// // order: PaginationOrder.a -// // } -// // component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); -// // component.changePage(2); -// // }); -// -// it('#changeNbItems() should change nbItems value and raise getData event', () => { -// component.dataset = DATASET; -// component.sortedCol = 1; -// component.sortedOrder = PaginationOrder.a; -// const expectedPagination: Pagination = { -// dname: 'cat_1', -// page: 1, -// nbItems: 20, -// sortedCol: 1, -// order: PaginationOrder.a -// } -// component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); -// component.changeNbItems(20); -// }); -// -// it('#sort() should raise getData event with correct parameters', () => { -// component.dataset = DATASET; -// component.sortedOrder = PaginationOrder.a; -// let expectedPagination: Pagination = { -// dname: 'cat_1', -// page: 1, -// nbItems: 10, -// sortedCol: 1, -// order: PaginationOrder.a -// } -// let subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); -// component.sort(1); -// subscribtion.unsubscribe(); -// component.sortedCol = 1; -// component.sortedOrder = PaginationOrder.a; -// expectedPagination = { -// dname: 'cat_1', -// page: 1, -// nbItems: 10, -// sortedCol: 1, -// order: PaginationOrder.d -// } -// subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); -// component.sort(1); -// subscribtion.unsubscribe(); -// component.sortedCol = 1; -// component.sortedOrder = PaginationOrder.d; -// expectedPagination = { -// dname: 'cat_1', -// page: 1, -// nbItems: 10, -// sortedCol: 1, -// order: PaginationOrder.a -// } -// subscribtion = component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); -// component.sort(1); -// }); -// -// it('#ngOnInit() should init sortedCol value', () => { -// component.attributeList = ATTRIBUTE_LIST; -// component.ngOnInit(); -// expect(component.sortedCol).toEqual(1); -// }); -// }); -// +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { of } from 'rxjs'; +import { AccordionModule } from 'ngx-bootstrap/accordion'; + +import { DatatableComponent } from './datatable.component'; +import * as fromDatatable from '../store/datatable.reducer'; +import * as datatableActions from '../store/datatable.action'; +import { Pagination, PaginationOrder } from '../store/model'; +import { ATTRIBUTE_LIST, DATASET } from '../../../../settings/test-data'; + +describe('[Shared][Datatable] Container: DatatableComponent', () => { + @Component({ selector: 'app-img', template: '' }) + class ImgStubComponent { + @Input() src: string; + } + + @Component({ selector: 'app-thumbnail', template: '' }) + class ThumbnailStubComponent { + @Input() src: string; + @Input() attributeName: string; + } + + @Component({ selector: 'app-link', template: '' }) + class LinkStubComponent { + @Input() href: string; + } + + @Component({ selector: 'app-btn', template: '' }) + class BtnStubComponent { + @Input() href: string; + } + + @Component({ selector: 'app-detail', template: '' }) + class DetailStubComponent { + @Input() style: string; + @Input() datasetName: string; + @Input() data: string | number; + } + + @Component({ selector: 'app-download', template: '' }) + class DownloadStubComponent { + @Input() href: string; + } + + @Component({ selector: 'app-json-renderer', template: '' }) + class JsonStubComponent { + @Input() attributeName: string; + @Input() json: string; + } + + @Component({ selector: 'pagination', template: '' }) + class PaginationStubComponent { + @Input() totalItems: number; + @Input() boundaryLinks: boolean; + @Input() rotate: boolean; + @Input() maxSize: number; + } + + let component: DatatableComponent; + let fixture: ComponentFixture; + let store: MockStore; + const initialState = { + datatable: { ...fromDatatable.initialState } + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + DatatableComponent, + ImgStubComponent, + ThumbnailStubComponent, + LinkStubComponent, + BtnStubComponent, + DetailStubComponent, + DownloadStubComponent, + JsonStubComponent, + PaginationStubComponent + ], + imports: [AccordionModule.forRoot(), BrowserAnimationsModule], + providers: [ provideMockStore({ initialState }) ] + }); + fixture = TestBed.createComponent(DatatableComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#ngOnInit() should init sortedCol value', () => { + const changeSortedColAction = new datatableActions.ChangeSortedColAction(1); + const spy = spyOn(store, 'dispatch'); + component.attributeList = ATTRIBUTE_LIST; + component.ngOnInit(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(changeSortedColAction); + }); + + it('should get page', () => { + expect(component.getPage()).toEqual(1); + }); + + it('should get nbItems', () => { + expect(component.getNbItems()).toEqual(10); + }); + + it('should get sortedCol', () => { + expect(component.getSortedCol()).toBeNull(); + component.sortedCol = of(1); + expect(component.getSortedCol()).toEqual(1); + }); + + it('should get sortedOrder', () => { + expect(component.getSortedOrder()).toEqual(PaginationOrder.a); + }); + + it('#requiredParams() should return if required params are defined', () => { + component.attributeList = ATTRIBUTE_LIST; + component.outputList = [1]; + component.dataLength = 1; + component.sortedCol = of(1); + expect(component.requiredParams()).toBeTruthy(); + component.dataLength = undefined; + expect(component.requiredParams()).toBeFalsy(); + component.dataLength = 1; + component.outputList = []; + expect(component.requiredParams()).toBeFalsy(); + component.outputList = [1]; + component.attributeList = []; + expect(component.requiredParams()).toBeFalsy(); + component.attributeList = ATTRIBUTE_LIST; + component.sortedCol = of(null); + expect(component.requiredParams()).toBeFalsy(); + }); + + it('#noSelectedData() should return true if no selectedData', () => { + component.selectedData = []; + expect(component.noSelectedData()).toBeTruthy(); + }); + + it('#noSelectedData() should return false if there are selectedData', () => { + component.selectedData = [123456]; + expect(component.noSelectedData()).toBeFalsy(); + }); + + it('#getOutputList() should return filtered output list', () => { + component.outputList = [2] + component.attributeList = ATTRIBUTE_LIST; + expect(component.getOutputList().length).toBe(1); + }); + + it('#toggleSelection(datum) should return add datum to selectedData', () => { + const datum = { label_one: 123456 }; + component.attributeList = ATTRIBUTE_LIST; + component.selectedData = []; + component.addSelectedData.subscribe((event: any) => expect(event).toBe(123456)); + component.toggleSelection(datum); + }); + + it('#toggleSelection(datum) should return remove datum to selectedData', () => { + const datum = { label_one: 123456 }; + component.selectedData = [123456]; + component.attributeList = ATTRIBUTE_LIST; + component.deleteSelectedData.subscribe((event: any) => expect(event).toBe(123456)); + component.toggleSelection(datum); + }); + + it('#isSelected(datum) should return true datum is selected', () => { + const datum = { label_one: 123456 }; + component.attributeList = ATTRIBUTE_LIST; + component.selectedData = [123456]; + expect(component.isSelected(datum)).toBeTruthy(); + }); + + it('#isSelected(datum) should return false datum is not selected', () => { + const datum = { label_one: 123456 }; + component.attributeList = ATTRIBUTE_LIST; + component.selectedData = []; + expect(component.isSelected(datum)).toBeFalsy(); + }); + + it('#changePage() should dispatch action to change page and call #updateDatatable()', () => { + component.dataset = DATASET; + const changePageAction = new datatableActions.ChangePageAction(2); + const spyDispatch = spyOn(store, 'dispatch'); + const spyUpdate = spyOn(component, 'updateDatatable'); + component.changePage(2); + expect(spyDispatch).toHaveBeenCalledTimes(1); + expect(spyDispatch).toHaveBeenCalledWith(changePageAction); + expect(spyUpdate).toHaveBeenCalledTimes(1); + }); + + it('#changeNbItems() should dispatch action to change nbItems and call #updateDatatable()', () => { + component.dataset = DATASET; + const changeNbItemsAction = new datatableActions.ChangeNbItemsAction(20); + const spyDispatch = spyOn(store, 'dispatch'); + const spyUpdate = spyOn(component, 'updateDatatable'); + component.changeNbItems(20); + expect(spyDispatch).toHaveBeenCalledTimes(1); + expect(spyDispatch).toHaveBeenCalledWith(changeNbItemsAction); + expect(spyUpdate).toHaveBeenCalledTimes(1); + }); + + it('#sort() should dispatch action to change sortedOrder to `d` and call #updateDatatable()', () => { + component.sortedCol = of(1); + const changeSortedOrderAction = new datatableActions.ChangeSortedOrderAction(PaginationOrder.d); + const spyDispatch = spyOn(store, 'dispatch'); + const spyUpdate = spyOn(component, 'updateDatatable'); + component.sort(1); + expect(spyDispatch).toHaveBeenCalledTimes(1); + expect(spyDispatch).toHaveBeenCalledWith(changeSortedOrderAction); + expect(spyUpdate).toHaveBeenCalledTimes(1); + }); + + it('#sort() should dispatch action to change sortedOrder to `a` and call #updateDatatable()', () => { + component.sortedCol = of(1); + component.sortedOrder = of(PaginationOrder.d); + const changeSortedOrderAction = new datatableActions.ChangeSortedOrderAction(PaginationOrder.a); + const spyDispatch = spyOn(store, 'dispatch'); + const spyUpdate = spyOn(component, 'updateDatatable'); + component.sort(1); + expect(spyDispatch).toHaveBeenCalledTimes(1); + expect(spyDispatch).toHaveBeenCalledWith(changeSortedOrderAction); + expect(spyUpdate).toHaveBeenCalledTimes(1); + }); + + it('#sort() should dispatch action to change sortedOrder and sortedCol and call #updateDatatable()', () => { + component.sortedCol = of(1); + const changeSortedColAction = new datatableActions.ChangeSortedColAction(2); + const changeSortedOrderAction = new datatableActions.ChangeSortedOrderAction(PaginationOrder.a); + const spyDispatch = spyOn(store, 'dispatch'); + const spyUpdate = spyOn(component, 'updateDatatable'); + component.sort(2); + expect(spyDispatch).toHaveBeenCalledTimes(2); + expect(spyDispatch).toHaveBeenCalledWith(changeSortedColAction); + expect(spyDispatch).toHaveBeenCalledWith(changeSortedOrderAction); + expect(spyUpdate).toHaveBeenCalledTimes(1); + }); + + it('#updateDatatable() should raise getData event', () => { + component.dataset = DATASET; + component.sortedCol = of(1); + const expectedPagination: Pagination = { + dname: 'cat_1', + page: 1, + nbItems: 10, + sortedCol: 1, + order: PaginationOrder.a + } + component.getData.subscribe((event: Pagination) => expect(event).toEqual(expectedPagination)); + component.updateDatatable(); + }); +}); + diff --git a/src/app/shared/datatable/containers/datatable.component.ts b/src/app/shared/datatable/containers/datatable.component.ts index 0c8a243..37464c3 100644 --- a/src/app/shared/datatable/containers/datatable.component.ts +++ b/src/app/shared/datatable/containers/datatable.component.ts @@ -73,7 +73,51 @@ export class DatatableComponent implements OnInit { } /** - * Checks if required parameters to display datatable are passed to the component. + * Returns page. + * + * @return number + */ + getPage(): number { + let page: number; + this.page.subscribe(p => page = p); + return page; + } + + /** + * Returns nbItems. + * + * @return number + */ + getNbItems(): number { + let nbItems: number; + this.nbItems.subscribe(nb => nbItems = nb); + return nbItems; + } + + /** + * Returns sortedCol. + * + * @return number + */ + getSortedCol(): number { + let sortedCol: number; + this.sortedCol.subscribe(col => sortedCol = col); + return sortedCol; + } + + /** + * Returns sortedOrder. + * + * @return PaginationOrder + */ + getSortedOrder(): PaginationOrder { + let sortedOrder: PaginationOrder; + this.sortedOrder.subscribe(order => sortedOrder = order); + return sortedOrder; + } + + /** + * Checks if required parameters to display datatable are defined. * * @return boolean */ @@ -138,41 +182,47 @@ export class DatatableComponent implements OnInit { } /** - * Emits event to update datatable. + * Changes the datatable page. * * @param {number} page - The datatable page number. - * @param {number} nbItems - The items number to be displayed per page. - * - * @fires EventEmitter */ - updateDatatable(page: number, nbItems: number): void { - const pagination: Pagination = { - dname: this.dataset.name, - page: page, - nbItems: nbItems, - sortedCol: this.getSortedCol(), - order: PaginationOrder.a - }; - this.getData.emit(pagination); + changePage(page: number): void { this.store.dispatch(new datatableActions.ChangePageAction(page)); + this.updateDatatable(); + } + + /** + * Changes the datatable page. + * + * @param {number} nbItems - The datatable items number. + */ + changeNbItems(nbItems: number): void { this.store.dispatch(new datatableActions.ChangeNbItemsAction(nbItems)); + this.updateDatatable(); } /** - * Emits event to change the sorted order and the sorted column of the datatable. + * Changes the sorted order and the sorted column of the datatable. * * @param {number} id - The id of the column to sort. - * - * @fires EventEmitter */ sort(id: number): void { - let order: PaginationOrder = PaginationOrder.a; if (id === this.getSortedCol()) { - order = this.getSortedOrder() === PaginationOrder.a ? PaginationOrder.d : PaginationOrder.a; + const order = this.getSortedOrder() === PaginationOrder.a ? PaginationOrder.d : PaginationOrder.a; + this.store.dispatch(new datatableActions.ChangeSortedOrderAction(order)); } else { this.store.dispatch(new datatableActions.ChangeSortedColAction(id)); + this.store.dispatch(new datatableActions.ChangeSortedOrderAction(PaginationOrder.a)); } - this.store.dispatch(new datatableActions.ChangeSortedOrderAction(order)); + this.updateDatatable(); + } + + /** + * Emits event to update datatable. + * + * @fires EventEmitter + */ + updateDatatable(): void { const pagination: Pagination = { dname: this.dataset.name, page: this.getPage(), @@ -182,48 +232,4 @@ export class DatatableComponent implements OnInit { }; this.getData.emit(pagination); } - - /** - * Returns page. - * - * @return number - */ - getPage(): number { - let page: number; - this.page.subscribe(p => page = p); - return page; - } - - /** - * Returns nbItems. - * - * @return number - */ - getNbItems(): number { - let nbItems: number; - this.nbItems.subscribe(nb => nbItems = nb); - return nbItems; - } - - /** - * Returns sortedCol. - * - * @return number - */ - getSortedCol(): number { - let sortedCol: number; - this.sortedCol.subscribe(col => sortedCol = col); - return sortedCol; - } - - /** - * Returns sortedOrder. - * - * @return PaginationOrder - */ - getSortedOrder(): PaginationOrder { - let sortedOrder: PaginationOrder; - this.sortedOrder.subscribe(order => sortedOrder = order); - return sortedOrder; - } } diff --git a/src/app/shared/datatable/index.ts b/src/app/shared/datatable/index.ts index 8b36006..b8f5247 100644 --- a/src/app/shared/datatable/index.ts +++ b/src/app/shared/datatable/index.ts @@ -1,11 +1,15 @@ import { DatatableComponent } from './containers/datatable.component'; -import { TablePaginationComponent } from './components/table-pagination.component'; -import { TableNbItemsComponent } from './components/table-nb-items.component'; -import { rendererComponents } from './components/renderer'; +import { DetailComponent } from './components/detail.component'; +import { ImageComponent } from './components/image.component'; +import { JsonComponent } from './components/json.component'; +import { LinkComponent } from './components/link.component'; +import { DownloadComponent } from './components/download.component'; export const datatableComponents = [ DatatableComponent, - TablePaginationComponent, - TableNbItemsComponent, - rendererComponents + DetailComponent, + ImageComponent, + JsonComponent, + LinkComponent, + DownloadComponent ]; -- GitLab From 8813bb861d55271676ff8b6a6dded30bfb4a5ee0 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas Date: Mon, 1 Feb 2021 17:39:28 +0100 Subject: [PATCH 12/16] Save visited object to store => DONE, Change style for visited links => DONE --- .../datatable/components/detail.component.css | 18 +++++++++++++ .../components/detail.component.html | 6 +++-- .../datatable/components/detail.component.ts | 4 ++- .../containers/datatable.component.html | 6 ++--- .../containers/datatable.component.spec.ts | 8 ++++++ .../containers/datatable.component.ts | 11 +++++++- .../datatable/store/datatable.action.ts | 2 +- .../datatable/store/datatable.reducer.spec.ts | 26 +++++++++---------- .../datatable/store/datatable.reducer.ts | 8 +++++- 9 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 src/app/shared/datatable/components/detail.component.css 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 0000000..5c1a8a2 --- /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 index 9fd2771..c350700 100644 --- a/src/app/shared/datatable/components/detail.component.html +++ b/src/app/shared/datatable/components/detail.component.html @@ -1,4 +1,6 @@ - + {{ value }} diff --git a/src/app/shared/datatable/components/detail.component.ts b/src/app/shared/datatable/components/detail.component.ts index 2bbcc88..84c98d6 100644 --- a/src/app/shared/datatable/components/detail.component.ts +++ b/src/app/shared/datatable/components/detail.component.ts @@ -7,7 +7,7 @@ * 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'; @@ -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/containers/datatable.component.html b/src/app/shared/datatable/containers/datatable.component.html index 8600e70..91d539f 100644 --- a/src/app/shared/datatable/containers/datatable.component.html +++ b/src/app/shared/datatable/containers/datatable.component.html @@ -44,8 +44,7 @@ - +