Skip to content

Commit

Permalink
Merged in feature/SHIBUI-707 (pull request #154)
Browse files Browse the repository at this point in the history
* SHIBUI-707 Implemented provider re-ordering

Approved-by: Shibui Jenkins <shibui.jenkins@gmail.com>
Approved-by: Ryan Mathis <rmathis@unicon.net>
  • Loading branch information
rmathis committed Aug 14, 2018
1 parent 97ae894 commit 4b0f3f6
Show file tree
Hide file tree
Showing 15 changed files with 410 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ViewChild, Component } from '@angular/core';
import { Observable, of } from 'rxjs';
import { PreviewDialogComponent } from './preview-dialog.component';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { NgbActiveModalStub } from '../../../../testing/modal.stub';

@Component({
template: `<preview-dialog></preview-dialog>`
})
class TestHostComponent {
@ViewChild(PreviewDialogComponent)
public formUnderTest: PreviewDialogComponent;
}


describe('Advanced Info Form Component', () => {
let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: NgbActiveModal, useClass: NgbActiveModalStub }
],
imports: [
NoopAnimationsModule,
ReactiveFormsModule
],
declarations: [
PreviewDialogComponent,
TestHostComponent
],
});

fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
fixture.detectChanges();
});

it('should compile', () => {
expect(fixture).toBeDefined();
});
});
3 changes: 3 additions & 0 deletions ui/src/app/metadata/domain/model/metadata-order.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface ProviderOrder {
resourceIds: string[];
}
10 changes: 10 additions & 0 deletions ui/src/app/metadata/domain/service/provider.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { Observable } from 'rxjs';

import { MetadataProvider } from '../../domain/model';
import { FileBackedHttpMetadataProvider } from '../model/providers';
import { ProviderOrder } from '../model/metadata-order';

@Injectable()
export class MetadataProviderService {

readonly endpoint = '/MetadataResolvers';
readonly order = '/MetadataResolversPositionOrder';
readonly base = '/api';

constructor(
Expand All @@ -29,4 +31,12 @@ export class MetadataProviderService {
save(provider: MetadataProvider): Observable<MetadataProvider> {
return this.http.post<MetadataProvider>(`${this.base}${this.endpoint}`, provider);
}

getOrder(): Observable<ProviderOrder> {
return this.http.get<ProviderOrder>(`${this.base}${this.order}`);
}

setOrder(order: ProviderOrder): Observable<ProviderOrder> {
return this.http.post<ProviderOrder>(`${this.base}${this.order}`, order);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<div class="card-header" (click)="toggle.emit(provider)" (keydown.space)="toggle.emit(provider)" tabindex="0">
<div class="d-flex">
<div class="reorder-card">
<p class="text-center text-primary font-weight-bold">1</p>
<button class="btn btn-link" disabled>
<p class="text-center text-primary font-weight-bold">{{ index }}</p>
<button class="btn btn-link" (click)="changeOrderDown.emit(provider); $event.stopPropagation();" [disabled]="last">
<i class="fa text-info fa-lg fa-chevron-circle-down" aria-hidden="true"></i>
</button>
<button class="btn btn-link pull-right" disabled>
<button class="btn btn-link pull-right" (click)="changeOrderUp.emit(provider); $event.stopPropagation();" [disabled]="first">
<i class="fa text-info fa-lg fa-chevron-circle-up" aria-hidden="true"></i>
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import { EntityItemComponent } from './entity-item.component';

export class ProviderItemComponent extends EntityItemComponent {
@Input() provider: MetadataProvider;
@Input() index: number;
@Input() first: boolean;
@Input() last: boolean;

@Output() viewFilters: EventEmitter<MetadataProvider> = new EventEmitter();

@Output() changeOrderUp: EventEmitter<MetadataProvider> = new EventEmitter();
@Output() changeOrderDown: EventEmitter<MetadataProvider> = new EventEmitter();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@
</div>
<div class="p-3">
<ul class="list-unstyled m-0">
<li *ngFor="let provider of providers$ | async; index as i"
<li *ngFor="let provider of providers$ | async; index as i; first as isFirst; last as isLast;"
[class.mt-2]="i > 0">
<provider-item
[index]="i + 1"
[first]="isFirst"
[last]="isLast"
[provider]="provider"
[isOpen]="(providersOpen$ | async)[provider.resourceId]"
(select)="edit(provider)"
(viewFilters)="gotoFilters(provider)"
(toggle)="toggleEntity(provider)">
(toggle)="toggleEntity(provider)"
(changeOrderUp)="updateOrderUp($event)"
(changeOrderDown)="updateOrderDown($event)">
</provider-item>
</li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MetadataProvider } from '../../domain/model';
import { Observable } from '../../../../../node_modules/rxjs';
import { Store } from '@ngrx/store';

import { ProviderState, getAllProviders } from '../../provider/reducer';
import * as fromDashboard from '../reducer';
import { ProviderState, getOrderedProviders } from '../../provider/reducer';
import { getOpenProviders } from '../reducer';
import { ToggleEntityDisplay } from '../action/manager.action';
import { map } from 'rxjs/operators';
import { ChangeOrderUp, ChangeOrderDown } from '../../provider/action/collection.action';

@Component({
selector: 'dashboard-providers-list',
templateUrl: './dashboard-providers-list.component.html'
})

export class DashboardProvidersListComponent {
export class DashboardProvidersListComponent implements OnInit {

providers$: Observable<MetadataProvider[]>;
providersOpen$: Observable<{ [key: string]: boolean }>;

constructor(
private store: Store<ProviderState>,
private router: Router
) {
this.providers$ = this.store.select(getAllProviders).pipe(
map(providers => providers.filter(p => p['@type'] !== 'BaseMetadataResolver'))
);
this.providersOpen$ = store.select(fromDashboard.getOpenProviders);
) { }

ngOnInit(): void {
this.providers$ = this.store.select(getOrderedProviders);
this.providersOpen$ = this.store.select(getOpenProviders);
this.providers$.subscribe(p => console.log(p));
}

view(id: string, page: string): void {
Expand All @@ -44,4 +46,12 @@ export class DashboardProvidersListComponent {
toggleEntity(provider: MetadataProvider): void {
this.store.dispatch(new ToggleEntityDisplay(provider.resourceId));
}

updateOrderUp(provider: MetadataProvider): void {
this.store.dispatch(new ChangeOrderUp(provider.resourceId));
}

updateOrderDown(provider: MetadataProvider): void {
this.store.dispatch(new ChangeOrderDown(provider.resourceId));
}
}
72 changes: 70 additions & 2 deletions ui/src/app/metadata/provider/action/collection.action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Action } from '@ngrx/store';
import { MetadataProvider } from '../../domain/model/metadata-provider';
import { Update } from '@ngrx/entity';
import { ProviderOrder } from '../../domain/model/metadata-order';

export enum ProviderCollectionActionTypes {
UPDATE_PROVIDER_REQUEST = '[Metadata Provider] Update Request',
Expand All @@ -21,7 +22,18 @@ export enum ProviderCollectionActionTypes {

REMOVE_PROVIDER_REQUEST = '[Metadata Provider Collection] Remove Provider Request',
REMOVE_PROVIDER_SUCCESS = '[Metadata Provider Collection] Remove Provider Success',
REMOVE_PROVIDER_FAIL = '[Metadata Provider Collection] Remove Provider Fail'
REMOVE_PROVIDER_FAIL = '[Metadata Provider Collection] Remove Provider Fail',

SET_ORDER_PROVIDER_REQUEST = '[Metadata Provider Collection] Set Order Provider Request',
SET_ORDER_PROVIDER_SUCCESS = '[Metadata Provider Collection] Set Order Remove Provider Success',
SET_ORDER_PROVIDER_FAIL = '[Metadata Provider Collection] Set Order Remove Provider Fail',

GET_ORDER_PROVIDER_REQUEST = '[Metadata Provider Collection] Get Order Remove Provider Request',
GET_ORDER_PROVIDER_SUCCESS = '[Metadata Provider Collection] Get Order Remove Provider Success',
GET_ORDER_PROVIDER_FAIL = '[Metadata Provider Collection] Get Order Remove Provider Fail',

CHANGE_PROVIDER_ORDER_UP = '[Metadata Provider Collection] Change Order Up',
CHANGE_PROVIDER_ORDER_DOWN = '[Metadata Provider Collection] Change Order Down',
}

export class LoadProviderRequest implements Action {
Expand Down Expand Up @@ -114,6 +126,54 @@ export class RemoveProviderFail implements Action {
constructor(public payload: MetadataProvider) { }
}

export class SetOrderProviderRequest implements Action {
readonly type = ProviderCollectionActionTypes.SET_ORDER_PROVIDER_REQUEST;

constructor(public payload: ProviderOrder) { }
}

export class SetOrderProviderSuccess implements Action {
readonly type = ProviderCollectionActionTypes.SET_ORDER_PROVIDER_SUCCESS;

constructor() { }
}

export class SetOrderProviderFail implements Action {
readonly type = ProviderCollectionActionTypes.SET_ORDER_PROVIDER_FAIL;

constructor(public payload: Error) { }
}

export class GetOrderProviderRequest implements Action {
readonly type = ProviderCollectionActionTypes.GET_ORDER_PROVIDER_REQUEST;

constructor() { }
}

export class GetOrderProviderSuccess implements Action {
readonly type = ProviderCollectionActionTypes.GET_ORDER_PROVIDER_SUCCESS;

constructor(public payload: ProviderOrder) { }
}

export class GetOrderProviderFail implements Action {
readonly type = ProviderCollectionActionTypes.GET_ORDER_PROVIDER_FAIL;

constructor(public payload: Error) { }
}

export class ChangeOrderUp implements Action {
readonly type = ProviderCollectionActionTypes.CHANGE_PROVIDER_ORDER_UP;

constructor(public payload: string) { }
}

export class ChangeOrderDown implements Action {
readonly type = ProviderCollectionActionTypes.CHANGE_PROVIDER_ORDER_DOWN;

constructor(public payload: string) { }
}

export type ProviderCollectionActionsUnion =
| LoadProviderRequest
| LoadProviderSuccess
Expand All @@ -129,4 +189,12 @@ export type ProviderCollectionActionsUnion =
| RemoveProviderFail
| UpdateProviderRequest
| UpdateProviderSuccess
| UpdateProviderFail;
| UpdateProviderFail
| SetOrderProviderRequest
| SetOrderProviderSuccess
| SetOrderProviderFail
| GetOrderProviderRequest
| GetOrderProviderSuccess
| GetOrderProviderFail
| ChangeOrderUp
| ChangeOrderDown;
90 changes: 89 additions & 1 deletion ui/src/app/metadata/provider/effect/collection.effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ import {
SelectProviderError,
UpdateProviderRequest,
UpdateProviderSuccess,
UpdateProviderFail
UpdateProviderFail,
GetOrderProviderRequest,
GetOrderProviderSuccess,
GetOrderProviderFail,
SetOrderProviderRequest,
SetOrderProviderSuccess,
SetOrderProviderFail,
ChangeOrderUp,
ChangeOrderDown
} from '../action/collection.action';
import { MetadataProviderService } from '../../domain/service/provider.service';
import * as fromProvider from '../reducer';
Expand Down Expand Up @@ -118,6 +126,86 @@ export class CollectionEffects {
map(provider => new LoadProviderRequest())
);

@Effect()
getOrderWithLoad$ = this.actions$.pipe(
ofType<LoadProviderSuccess>(ProviderCollectionActionTypes.LOAD_PROVIDER_SUCCESS),
map(() => new GetOrderProviderRequest())
);

@Effect()
getProviderOrder$ = this.actions$.pipe(
ofType<GetOrderProviderRequest>(ProviderCollectionActionTypes.GET_ORDER_PROVIDER_REQUEST),
switchMap(() =>
this.providerService.getOrder().pipe(
map(order => new GetOrderProviderSuccess(order)),
catchError(err => of(new GetOrderProviderFail(err)))
)
)
);

@Effect()
reloadProviderOrderAfterChange$ = this.actions$.pipe(
ofType<SetOrderProviderSuccess>(ProviderCollectionActionTypes.SET_ORDER_PROVIDER_SUCCESS),
map(() => new GetOrderProviderRequest())
);

@Effect()
setProviderOrder$ = this.actions$.pipe(
ofType<SetOrderProviderRequest>(ProviderCollectionActionTypes.SET_ORDER_PROVIDER_REQUEST),
map(action => action.payload),
switchMap(order =>
this.providerService.setOrder(order).pipe(
map(() => new SetOrderProviderSuccess()),
catchError(err => of(new SetOrderProviderFail(err)))
)
)
);

@Effect()
changeOrderUp$ = this.actions$.pipe(
ofType<ChangeOrderUp>(ProviderCollectionActionTypes.CHANGE_PROVIDER_ORDER_UP),
map(action => action.payload),
withLatestFrom(this.store.select(fromProvider.getProviderOrder)),
map(([id, orderSet]) => {
const order = orderSet.resourceIds;
const index = order.indexOf(id);
if (index > 0) {
const newOrder = this.array_move(order, index, index - 1);
return new SetOrderProviderRequest({ resourceIds: newOrder });
} else {
return new SetOrderProviderFail(new Error(`could not change order: ${ id }`));
}
})
);

@Effect()
changeOrderDown$ = this.actions$.pipe(
ofType<ChangeOrderDown>(ProviderCollectionActionTypes.CHANGE_PROVIDER_ORDER_DOWN),
map(action => action.payload),
withLatestFrom(this.store.select(fromProvider.getProviderOrder)),
map(([id, orderSet]) => {
const order = orderSet.resourceIds;
const index = order.indexOf(id);
if (index < order.length - 1) {
const newOrder = this.array_move(order, index, index + 1);
return new SetOrderProviderRequest({ resourceIds: newOrder });
} else {
return new SetOrderProviderFail(new Error(`could not change order: ${id}`));
}
})
);

array_move(arr, old_index, new_index): any[] {
if (new_index >= arr.length) {
let k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr;
}

constructor(
private actions$: Actions,
private router: Router,
Expand Down
Loading

0 comments on commit 4b0f3f6

Please sign in to comment.