diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 389162b05..e04fe3b90 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -393,6 +393,8 @@ label.title=Title label.enabled=Enabled label.author=Author label.creation-date=Creation Date +label.order=Order +label.provider-type=Provider Type label.metadata-resolver-history=Metadata resolver history label.metadata-version-history=Metadata Version History diff --git a/ui/src/app/admin/component/enable-metadata.component.html b/ui/src/app/admin/component/enable-metadata.component.html index cba54f177..01465184f 100644 --- a/ui/src/app/admin/component/enable-metadata.component.html +++ b/ui/src/app/admin/component/enable-metadata.component.html @@ -4,9 +4,8 @@ aria-label="Provider Item Accordion. Press Spacebar to open"> resolvers.map(r => new FileBackedHttpMetadataResolver(r))) ); this.loading$ = this.store.select(fromDashboard.getSearchLoading); - this.entitiesOpen$ = this.store.select(fromDashboard.getOpenProviders); this.total$ = this.resolvers$.pipe(map(list => list.length)); } @@ -51,10 +49,6 @@ export class EnableMetadataComponent implements OnInit { this.router.navigate(['metadata', 'resolver', entity.getId(), 'edit']); } - toggleEntity(entity: MetadataEntity): void { - this.store.dispatch(new ToggleEntityDisplay(entity.getId())); - } - openPreviewDialog(entity: MetadataEntity): void { this.store.dispatch(new PreviewEntity({ id: entity.getId(), entity })); } diff --git a/ui/src/app/core/model/action.ts b/ui/src/app/core/model/action.ts index 6d796da39..2f7e1ca3c 100644 --- a/ui/src/app/core/model/action.ts +++ b/ui/src/app/core/model/action.ts @@ -1,6 +1,6 @@ export interface NavigationAction { action: ($event: Event) => void; - category: string; + category?: string; label: string; content: string; icon?: string; diff --git a/ui/src/app/core/service/navigation.service.spec.ts b/ui/src/app/core/service/navigation.service.spec.ts new file mode 100644 index 000000000..d036019e4 --- /dev/null +++ b/ui/src/app/core/service/navigation.service.spec.ts @@ -0,0 +1,50 @@ +import { TestBed, async } from '@angular/core/testing'; + +import { NavigationService } from './navigation.service'; + +describe('Navigation Service', () => { + let service: NavigationService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [], + providers: [ + NavigationService + ] + }); + service = TestBed.get(NavigationService); + }); + + it('should instantiate', () => { + expect(service).toBeDefined(); + }); + + describe('addAction method', () => { + it('should add a navigation option to the list of actions', () => { + service.addAction('foo', { + action: () => {}, + category: 'bar', + label: 'baz', + content: 'something' + }); + + expect(service.actionList.length).toBe(1); + }); + + it('should emit the value from an observable when an action is added', (done: DoneFn) => { + const action = { + action: () => { }, + category: 'bar', + label: 'baz', + content: 'something' + }; + const actionName = 'foo'; + service.addAction(actionName, action); + + service.emitter.subscribe((actions) => { + expect(actions.length).toBe(1); + done(); + }); + }); + }); +}); diff --git a/ui/src/app/core/service/navigation.service.ts b/ui/src/app/core/service/navigation.service.ts index 4d6f3821e..dc7b01342 100644 --- a/ui/src/app/core/service/navigation.service.ts +++ b/ui/src/app/core/service/navigation.service.ts @@ -23,7 +23,6 @@ export class NavigationService { } addAction(name: string, action: NavigationAction): NavigationAction[] { - console.log(this.actions); this.actions[name] = action; this.subj.next(this.actionList); return this.actionList; diff --git a/ui/src/app/metadata/manager/action/manager.action.ts b/ui/src/app/metadata/manager/action/manager.action.ts deleted file mode 100644 index cf95aa494..000000000 --- a/ui/src/app/metadata/manager/action/manager.action.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Action } from '@ngrx/store'; - -export const TOGGLE_ENTITY_DISPLAY = '[Dashboard] Display Entity'; - -export class ToggleEntityDisplay implements Action { - readonly type = TOGGLE_ENTITY_DISPLAY; - - constructor(public payload: string) { } -} - -export type Actions = - | ToggleEntityDisplay; diff --git a/ui/src/app/metadata/manager/action/search.action.ts b/ui/src/app/metadata/manager/action/search.action.ts index 457a9c371..c10361a81 100644 --- a/ui/src/app/metadata/manager/action/search.action.ts +++ b/ui/src/app/metadata/manager/action/search.action.ts @@ -1,32 +1,34 @@ -import { Action } from '@ngrx/store'; -import { MetadataEntity } from '../../domain/model'; +import { Action, MemoizedSelector } from '@ngrx/store'; +import { Metadata } from '../../domain/domain.type'; -export const ENTITY_SEARCH = '[Metadata Entity Search] Entity Search'; -export const ENTITY_FILTER = '[Metadata Entity Filter] Entity Filter'; -export const ENTITY_SEARCH_COMPLETE = '[Metadata Entity Search] Entity Search COMPLETE'; +export enum DashboardSearchActionTypes { + ENTITY_SEARCH_COMPLETE = '[Metadata Entity Search] Entity Search COMPLETE', + ENTITY_FILTER = '[Metadata Entity Filter] Entity Filter', + ENTITY_SEARCH = '[Metadata Entity Search] Entity Search', +} /** * Add Resolver to Collection Actions */ export class SearchAction implements Action { - readonly type = ENTITY_SEARCH; + readonly type = DashboardSearchActionTypes.ENTITY_SEARCH; - constructor(public payload: string) { } + constructor(public payload: { query: string, selector: MemoizedSelector }) { } } export class FilterAction implements Action { - readonly type = ENTITY_FILTER; + readonly type = DashboardSearchActionTypes.ENTITY_FILTER; constructor(public payload: string) { } } export class SearchCompleteAction implements Action { - readonly type = ENTITY_SEARCH_COMPLETE; + readonly type = DashboardSearchActionTypes.ENTITY_SEARCH_COMPLETE; - constructor(public payload: Array) { } + constructor(public payload: Array) { } } -export type Actions = +export type DashboardSearchActionsUnion = | SearchAction | FilterAction | SearchCompleteAction; diff --git a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.html b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.html index b0f47ee04..07d0bf58d 100644 --- a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.html +++ b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.html @@ -8,6 +8,62 @@
+ + +
+ + + + + + + + + + + + + + + + + + + +
OrderTitleProvider TypeAuthorCreated DateEnabled
+
+
{{ i }}
+
+   + + +
+
+ {{ provider.name }} + {{ provider['@type'] }}{{ provider.createdBy }}{{ provider.createdDate | customDate : '—' }} + + Enabled + Enabled + +
+
+
diff --git a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.scss b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.scss new file mode 100644 index 000000000..133f4a03c --- /dev/null +++ b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.scss @@ -0,0 +1,14 @@ +@import '../../../../theme/palette'; +.provider-index { + font-size: 1.8rem; + line-height: 1.8rem; + font-weight: lighter; + font-family: monospace; + width: 45px; +} + +.table-providers { + tr > td { + vertical-align: middle; + } +} \ No newline at end of file diff --git a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.spec.ts b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.spec.ts index 1a8c447e3..4b5d1c38a 100644 --- a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.spec.ts +++ b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.spec.ts @@ -1,6 +1,6 @@ import { TestBed, ComponentFixture } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { Router } from '@angular/router'; +import { Router, RouterModule } from '@angular/router'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; import { NgbPaginationModule, NgbModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; @@ -12,10 +12,10 @@ import { NgbModalStub } from '../../../../testing/modal.stub'; import { DashboardProvidersListComponent } from './dashboard-providers-list.component'; import { MetadataProvider } from '../../domain/model'; import { ProviderItemComponent } from '../component/provider-item.component'; -import { FileBackedHttpMetadataResolver } from '../../domain/entity'; import { MockI18nModule } from '../../../../testing/i18n.stub'; import { CustomDatePipe } from '../../../shared/pipe/date.pipe'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; +import { InfiniteScrollModule } from 'ngx-infinite-scroll'; describe('Dashboard Providers List Page', () => { @@ -30,6 +30,8 @@ describe('Dashboard Providers List Page', () => { name: 'bar' }; + let dispatchSpy, selectSpy; + beforeEach(() => { TestBed.configureTestingModule({ providers: [ @@ -44,7 +46,9 @@ describe('Dashboard Providers List Page', () => { ReactiveFormsModule, NgbPaginationModule, NgbModalModule, - MockI18nModule + MockI18nModule, + InfiniteScrollModule, + RouterModule ], declarations: [ DashboardProvidersListComponent, @@ -61,8 +65,8 @@ describe('Dashboard Providers List Page', () => { router = TestBed.get(Router); modal = TestBed.get(NgbModal); - spyOn(store, 'dispatch').and.callThrough(); - spyOn(store, 'select').and.returnValues(of([]), of({'foo': true})); + dispatchSpy = spyOn(store, 'dispatch').and.callThrough(); + selectSpy = spyOn(store, 'select').and.returnValues(of([]), of({'foo': true})); }); it('should compile', () => { @@ -71,10 +75,19 @@ describe('Dashboard Providers List Page', () => { expect(fixture).toBeDefined(); }); - describe('toggleProvider method', () => { - it('should fire a redux action', () => { - instance.toggleEntity(provider); + describe('search method', () => { + it('should default to an empty string', () => { + instance.search(); expect(store.dispatch).toHaveBeenCalled(); + const action = dispatchSpy.calls.mostRecent().args[0]; + expect(action.payload.query).toBe(''); + }); + + it('should search with the provided query string', () => { + instance.search('foo'); + expect(store.dispatch).toHaveBeenCalled(); + const action = dispatchSpy.calls.mostRecent().args[0]; + expect(action.payload.query).toBe('foo'); }); }); @@ -85,4 +98,23 @@ describe('Dashboard Providers List Page', () => { expect(router.navigate).toHaveBeenCalledWith(['metadata', 'provider', provider.resourceId, 'edit']); }); }); + + describe('loadMore method', () => { + it('should call the page observable to emit the next value', (done: DoneFn) => { + instance.loadMore(5); + instance.page$.subscribe(val => { + expect(val).toBe(5); + expect(instance.page).toBe(5); + done(); + }); + }); + }); + + describe('onScroll method', () => { + it('should call the loadMore method', () => { + spyOn(instance, 'loadMore'); + instance.onScroll(new Event('scrolled')); + expect(instance.loadMore).toHaveBeenCalledWith(instance.page + 1); + }); + }); }); diff --git a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.ts b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.ts index de7c3644f..6d09cf0fa 100644 --- a/ui/src/app/metadata/manager/container/dashboard-providers-list.component.ts +++ b/ui/src/app/metadata/manager/container/dashboard-providers-list.component.ts @@ -1,34 +1,80 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { MetadataProvider } from '../../domain/model'; -import { Observable } from '../../../../../node_modules/rxjs'; +import { Observable, BehaviorSubject, combineLatest } from 'rxjs'; import { Store } from '@ngrx/store'; -import { ProviderState, getOrderedProviders } from '../../provider/reducer'; -import { getOpenProviders } from '../reducer'; -import { ToggleEntityDisplay } from '../action/manager.action'; -import { map } from 'rxjs/operators'; +import { ProviderState, getOrderedProvidersInSearch, getOrderedProviders } from '../../provider/reducer'; +import * as fromDashboard from '../reducer'; +import { map, startWith } from 'rxjs/operators'; import { ChangeProviderOrderUp, ChangeProviderOrderDown } from '../../provider/action/collection.action'; import { Metadata } from '../../domain/domain.type'; +import { MetadataProvider } from '../../domain/model'; +import { SearchAction } from '../action/search.action'; +import { withLatestFrom } from 'rxjs/operators'; @Component({ selector: 'dashboard-providers-list', - templateUrl: './dashboard-providers-list.component.html' + templateUrl: './dashboard-providers-list.component.html', + styleUrls: ['./dashboard-providers-list.component.scss'] }) export class DashboardProvidersListComponent implements OnInit { - providers$: Observable; - providersOpen$: Observable<{ [key: string]: boolean }>; + providers$: Observable; + searchQuery$: Observable; + loading$: Observable; + + total$: Observable; + page = 1; + limit = 20; + limited$: Observable; + + isSearching$: Observable; + + private subj: BehaviorSubject = new BehaviorSubject(this.page); + readonly page$: Observable = this.subj.asObservable(); constructor( private store: Store, private router: Router - ) { } + ) { + const providers = this.store.select(fromDashboard.getSearchResults) as Observable; + this.providers$ = providers as Observable; + + this.searchQuery$ = store.select(fromDashboard.getSearchQuery); + this.loading$ = store.select(fromDashboard.getSearchLoading); + + this.total$ = this.providers$.pipe(map(list => list.length)); + + this.isSearching$ = this.searchQuery$.pipe(map(q => q.length > 0)); + + this.limited$ = combineLatest( + this.providers$, + this.page$ + ).pipe( + map(([list, page]) => { + let maxIndex = (page * this.limit) - 1, + minIndex = 0; + return list.filter((provider: Metadata, index: number) => (maxIndex >= index && index >= minIndex)); + }) + ); + } ngOnInit(): void { - this.providers$ = this.store.select(getOrderedProviders); - this.providersOpen$ = this.store.select(getOpenProviders); + this.search(); + } + + loadMore(index: number): void { + this.subj.next(index); + this.page = index; + } + + search(query: string = ''): void { + this.store.dispatch(new SearchAction({query, selector: getOrderedProviders})); + } + + onScroll(event: Event): void { + this.loadMore(this.page + 1); } view(id: string, page: string): void { @@ -43,10 +89,6 @@ export class DashboardProvidersListComponent implements OnInit { this.view(provider.resourceId, 'filters'); } - toggleEntity(provider: MetadataProvider): void { - this.store.dispatch(new ToggleEntityDisplay(provider.resourceId)); - } - updateOrderUp(provider: MetadataProvider): void { this.store.dispatch(new ChangeProviderOrderUp(provider.resourceId)); } diff --git a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts index 14a153197..0bbaa7f59 100644 --- a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts +++ b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts @@ -76,13 +76,6 @@ describe('Dashboard Resolvers List Page', () => { expect(fixture).toBeDefined(); }); - describe('toggleResolver method', () => { - it('should fire a redux action', () => { - instance.toggleEntity(draft); - expect(store.dispatch).toHaveBeenCalled(); - }); - }); - describe('search method', () => { it('should fire a redux action', () => { instance.search(); @@ -107,6 +100,25 @@ describe('Dashboard Resolvers List Page', () => { }); }); + describe('loadMore method', () => { + it('should call the page observable to emit the next value', (done: DoneFn) => { + instance.loadMore(5); + instance.page$.subscribe(val => { + expect(val).toBe(5); + expect(instance.page).toBe(5); + done(); + }); + }); + }); + + describe('onScroll method', () => { + it('should call the loadMore method', () => { + spyOn(instance, 'loadMore'); + instance.onScroll(new Event('scrolled')); + expect(instance.loadMore).toHaveBeenCalledWith(instance.page + 1); + }); + }); + describe('deleteResolver method', () => { it('should call the modal service', () => { spyOn(modal, 'open').and.callFake(() => { diff --git a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts index bde5bc624..3e298d14d 100644 --- a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts +++ b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts @@ -1,16 +1,17 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { Observable } from 'rxjs'; +import { Observable, BehaviorSubject, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import { MetadataEntity, MetadataResolver } from '../../domain/model'; import * as searchActions from '../action/search.action'; import * as fromDashboard from '../reducer'; -import { ToggleEntityDisplay } from '../action/manager.action'; import { DeleteDialogComponent } from '../component/delete-dialog.component'; import { RemoveDraftRequest } from '../../resolver/action/draft.action'; +import { getAllResolvers } from '../../resolver/reducer'; +import { FileBackedHttpMetadataResolver } from '../../domain/entity'; @Component({ selector: 'dashboard-resolvers-list', @@ -27,30 +28,26 @@ export class DashboardResolversListComponent implements OnInit { limit = 20; limited$: Observable; - entitiesOpen$: Observable<{ [key: string]: boolean }>; + private subj: BehaviorSubject = new BehaviorSubject(this.page); + readonly page$: Observable = this.subj.asObservable(); constructor( private store: Store, private router: Router, private modalService: NgbModal ) { - this.resolvers$ = store.select(fromDashboard.getSearchResults); + const resolvers: unknown = store.select(fromDashboard.getSearchResults); + this.resolvers$ = (resolvers as Observable) + .pipe( + map(list => list.map(resolver => new FileBackedHttpMetadataResolver(resolver as MetadataResolver))) + ); this.searchQuery$ = store.select(fromDashboard.getSearchQuery); this.loading$ = store.select(fromDashboard.getSearchLoading); - this.entitiesOpen$ = store.select(fromDashboard.getOpenProviders); this.total$ = this.resolvers$.pipe(map(list => list.length)); - this.limited$ = this.getPagedResolvers(this.page, this.resolvers$); - } - - ngOnInit(): void { - this.search(); - } - - getPagedResolvers(page: number, list$: Observable): Observable { - return list$.pipe( - map((providers: MetadataEntity[]) => { + this.limited$ = combineLatest(this.resolvers$, this.page$).pipe( + map(([providers, page]) => { let maxIndex = (page * this.limit) - 1, minIndex = 0; return providers.filter((resolver: MetadataEntity, index: number) => (maxIndex >= index && index >= minIndex)); @@ -58,13 +55,17 @@ export class DashboardResolversListComponent implements OnInit { ); } + ngOnInit(): void { + this.search(); + } + loadMore(index: number): void { + this.subj.next(index); this.page = index; - this.limited$ = this.getPagedResolvers(index, this.resolvers$); } search(query: string = ''): void { - this.store.dispatch(new searchActions.SearchAction(query)); + this.store.dispatch(new searchActions.SearchAction({query, selector: getAllResolvers})); this.page = 1; } @@ -81,10 +82,6 @@ export class DashboardResolversListComponent implements OnInit { }); } - toggleEntity(entity: MetadataEntity): void { - this.store.dispatch(new ToggleEntityDisplay(entity.getId())); - } - viewMetadataHistory(entity: MetadataEntity): void { this.router.navigate(['metadata', 'resolver', entity.getId(), 'versions']); } diff --git a/ui/src/app/metadata/manager/effect/search.effects.ts b/ui/src/app/metadata/manager/effect/search.effects.ts index e1da7c539..81ce788c4 100644 --- a/ui/src/app/metadata/manager/effect/search.effects.ts +++ b/ui/src/app/metadata/manager/effect/search.effects.ts @@ -1,23 +1,27 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; -import { Store } from '@ngrx/store'; +import { Store, MemoizedSelector } from '@ngrx/store'; import { Observable, of } from 'rxjs'; import { switchMap, map, combineLatest } from 'rxjs/operators'; -import * as entitySearch from '../action/search.action'; +import { + DashboardSearchActionTypes, + SearchAction, + DashboardSearchActionsUnion, + SearchCompleteAction +} from '../action/search.action'; import * as fromManager from '../reducer'; -import * as fromResolver from '../../resolver/reducer'; -import { MetadataProvider } from '../../domain/model/metadata-provider'; -import { FileBackedHttpMetadataResolver } from '../../domain/entity'; +import { Metadata } from '../../domain/domain.type'; +import { MetadataResolver } from '../../domain/model'; @Injectable() export class SearchEffects { @Effect() - search$ = this.actions$.pipe( - ofType(entitySearch.ENTITY_SEARCH), + searchResolvers$ = this.actions$.pipe( + ofType(DashboardSearchActionTypes.ENTITY_SEARCH), map(action => action.payload), - switchMap(() => this.performSearch()) + switchMap(({ selector }) => this.performSearch(selector)) ); matcher = (value, query) => value ? value.toLocaleLowerCase().match(query.toLocaleLowerCase()) : false; @@ -27,26 +31,21 @@ export class SearchEffects { private store: Store ) { } - private performSearch(): Observable { + private performSearch(selector: MemoizedSelector): Observable { return of([]).pipe( combineLatest( - this.store.select(fromResolver.getAllResolvers), - (o: any[], p: MetadataProvider[]): Array => { - return o.concat( - p.map(provider => new FileBackedHttpMetadataResolver(provider)) - ); - } + this.store.select(selector), + (o: any[], p: Metadata[]): Array => o.concat(p) ), combineLatest( this.store.select(fromManager.getSearchQuery), - (entities, term) => { - const filtered = entities.filter( - e => this.matcher(e.name, term) || this.matcher(e.entityId, term) - ); - return filtered; - } + (entities, term) => + entities.filter( + e => this.matcher(e.name, term) ? true : + ('entityId' in e) ? this.matcher((e as MetadataResolver).entityId, term) : this.matcher(e['@type'], term) + ) ), - map(entities => new entitySearch.SearchCompleteAction(entities)) + map(entities => new SearchCompleteAction(entities)) ); } } /* istanbul ignore next */ diff --git a/ui/src/app/metadata/manager/reducer/index.ts b/ui/src/app/metadata/manager/reducer/index.ts index 584760916..7c308183c 100644 --- a/ui/src/app/metadata/manager/reducer/index.ts +++ b/ui/src/app/metadata/manager/reducer/index.ts @@ -1,10 +1,8 @@ import { createSelector, createFeatureSelector } from '@ngrx/store'; import * as fromRoot from '../../../core/reducer'; -import * as fromDashboard from './manager.reducer'; import * as fromSearch from './search.reducer'; export interface DashboardState { - manager: fromDashboard.State; search: fromSearch.SearchState; } @@ -13,13 +11,10 @@ export interface State extends fromRoot.State { } export const reducers = { - manager: fromDashboard.reducer, search: fromSearch.reducer }; export const getFeatureState = createFeatureSelector('manager'); -export const getDashboardState = createSelector(getFeatureState, (state: DashboardState) => state.manager); -export const getOpenProviders = createSelector(getDashboardState, (manager: fromDashboard.State) => manager.resolversOpen); export const getSearchState = createSelector(getFeatureState, (state: DashboardState) => state.search diff --git a/ui/src/app/metadata/manager/reducer/manager.reducer.spec.ts b/ui/src/app/metadata/manager/reducer/manager.reducer.spec.ts deleted file mode 100644 index 9a57ad2fc..000000000 --- a/ui/src/app/metadata/manager/reducer/manager.reducer.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { reducer } from './manager.reducer'; -import * as fromDashboard from './manager.reducer'; -import { ToggleEntityDisplay } from '../action/manager.action'; - -describe('Dashboard Reducer', () => { - const initialState: fromDashboard.State = { - resolversOpen: {} - }; - - describe('undefined action', () => { - it('should return the default state', () => { - const result = reducer(undefined, {} as any); - - expect(result).toEqual(initialState); - }); - }); - - describe('Toggle Resolver Display', () => { - it('should toggle the selected providers open state', () => { - const id = 'foo'; - const action = new ToggleEntityDisplay(id); - - const result = reducer(initialState, action); - - expect(result).toEqual( - Object.assign({}, initialState, { resolversOpen: { foo: true } }) - ); - }); - }); -}); diff --git a/ui/src/app/metadata/manager/reducer/manager.reducer.ts b/ui/src/app/metadata/manager/reducer/manager.reducer.ts deleted file mode 100644 index b37bb940f..000000000 --- a/ui/src/app/metadata/manager/reducer/manager.reducer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as manager from '../action/manager.action'; - -export interface State { - resolversOpen: {[key: string]: boolean}; -} - -export const initialState: State = { - resolversOpen: {} -}; - -export function reducer(state = initialState, action: manager.Actions): State { - switch (action.type) { - case manager.TOGGLE_ENTITY_DISPLAY: { - return { - ...state, - resolversOpen: { - ...state.resolversOpen, - ...{[action.payload]: !state.resolversOpen[action.payload]} - } - }; - } - default: { - // console.log(state); - return state; - } - } -} - -export const resolversOpen = (state: State) => state.resolversOpen; diff --git a/ui/src/app/metadata/manager/reducer/search.reducer.ts b/ui/src/app/metadata/manager/reducer/search.reducer.ts index 17e700abd..38b6cf327 100644 --- a/ui/src/app/metadata/manager/reducer/search.reducer.ts +++ b/ui/src/app/metadata/manager/reducer/search.reducer.ts @@ -1,8 +1,8 @@ -import * as searchActions from '../action/search.action'; -import { MetadataEntity } from '../../domain/model'; +import { DashboardSearchActionTypes, DashboardSearchActionsUnion } from '../action/search.action'; +import { Metadata } from '../../domain/domain.type'; export interface SearchState { - entities: MetadataEntity[]; + entities: Metadata[]; loading: boolean; query: string; } @@ -13,17 +13,17 @@ const initialState: SearchState = { query: '' }; -export function reducer(state = initialState, action: searchActions.Actions): SearchState { +export function reducer(state = initialState, action: DashboardSearchActionsUnion): SearchState { switch (action.type) { - case searchActions.ENTITY_SEARCH: { + case DashboardSearchActionTypes.ENTITY_SEARCH: { return { ...state, - query: action.payload, + query: action.payload.query, loading: true, }; } - case searchActions.ENTITY_SEARCH_COMPLETE: { + case DashboardSearchActionTypes.ENTITY_SEARCH_COMPLETE: { return { entities: action.payload, loading: false, diff --git a/ui/src/app/metadata/provider/effect/collection.effect.ts b/ui/src/app/metadata/provider/effect/collection.effect.ts index 7091e46d8..8b1003912 100644 --- a/ui/src/app/metadata/provider/effect/collection.effect.ts +++ b/ui/src/app/metadata/provider/effect/collection.effect.ts @@ -235,6 +235,7 @@ export class CollectionEffects { withLatestFrom(this.store.select(fromProvider.getProviderOrder)), map(([id, order]) => { const index = order.indexOf(id); + console.log(id, order); if (index > 0) { const newOrder = array_move(order, index, index - 1); return new SetOrderProviderRequest(newOrder); diff --git a/ui/src/app/metadata/provider/reducer/index.ts b/ui/src/app/metadata/provider/reducer/index.ts index c05a233e3..d40313299 100644 --- a/ui/src/app/metadata/provider/reducer/index.ts +++ b/ui/src/app/metadata/provider/reducer/index.ts @@ -71,3 +71,4 @@ export const getProviderFilters = createSelector(getSelectedProvider, provider = export const getProviderXmlIds = createSelector(getAllProviders, (providers: MetadataProvider[]) => providers.map(p => p.xmlId)); export const getOrderedProviders = createSelector(getAllProviders, getProviderOrder, utils.mergeOrderFn); +export const getOrderedProvidersInSearch = createSelector(getAllProviders, getProviderOrder, utils.mergeOrderFn);