Fix empty error & Integration / shops split test | real shops (#233)

This commit is contained in:
Rinat Arsaev 2020-05-20 14:02:23 +03:00 committed by GitHub
parent 17afdd69e3
commit 239dbc7def
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 106 additions and 83 deletions

View File

@ -2,6 +2,7 @@
"printWidth": 120,
"singleQuote": true,
"tabWidth": 4,
"endOfLine": "auto",
"overrides": [
{
"files": "*.svg",

View File

@ -1,7 +1,8 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TranslocoService } from '@ngneat/transloco';
import { Shop } from '../../../../../api-codegen/capi';
import { ShopsPanelsListService } from './shops-panels-list.service';
@Component({
@ -11,6 +12,13 @@ import { ShopsPanelsListService } from './shops-panels-list.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShopsPanelsListComponent {
@Input() set shops(shops: Shop[]) {
this.shopsPanelsListService.updateShops(shops);
}
@Output() activateShop = new EventEmitter<string>();
@Output() suspendShop = new EventEmitter<string>();
shops$ = this.shopsPanelsListService.shops$;
selectedPanelPosition$ = this.shopsPanelsListService.selectedPanelPosition$;
hasMore$ = this.shopsPanelsListService.hasMore$;
@ -30,11 +38,11 @@ export class ShopsPanelsListComponent {
}
suspend(id: string) {
this.shopsPanelsListService.suspend(id);
this.suspendShop.emit(id);
}
activate(id: string) {
this.shopsPanelsListService.activate(id);
this.activateShop.emit(id);
}
showMore() {

View File

@ -1,25 +1,19 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslocoService } from '@ngneat/transloco';
import { combineLatest, concat, Subject } from 'rxjs';
import { filter, first, map, mapTo, pluck, scan, shareReplay, switchMap } from 'rxjs/operators';
import { combineLatest, concat, ReplaySubject, Subject } from 'rxjs';
import { map, mapTo, pluck, scan, shareReplay, take } from 'rxjs/operators';
import { ConfirmActionDialogComponent } from '@dsh/components/popups';
import { ShopService } from '../../../../../api';
import { Shop } from '../../../../../api-codegen/capi';
import { SHARE_REPLAY_CONF } from '../../../../../custom-operators';
import { ShopsService } from '../shops.service';
const SHOPS_LIMIT = 10;
@Injectable()
export class ShopsPanelsListService {
private allShops$ = new ReplaySubject<Shop[]>(1);
private showMore$ = new Subject<void>();
selectedPanelPosition$ = combineLatest([this.route.fragment, this.shopsService.shops$]).pipe(
first(),
selectedPanelPosition$ = combineLatest([this.route.fragment.pipe(take(1)), this.allShops$]).pipe(
map(([fragment, shops]) => shops.findIndex(({ id }) => id === fragment)),
shareReplay(SHARE_REPLAY_CONF)
);
@ -32,74 +26,32 @@ export class ShopsPanelsListService {
shareReplay(SHARE_REPLAY_CONF)
);
shops$ = combineLatest([this.shopService.shops$, this.offset$]).pipe(
shops$ = combineLatest([this.allShops$, this.offset$]).pipe(
map(([shops, showedCount]) => shops.slice(0, showedCount)),
shareReplay(SHARE_REPLAY_CONF)
);
hasMore$ = combineLatest([this.shopService.shops$.pipe(pluck('length')), this.offset$]).pipe(
hasMore$ = combineLatest([this.allShops$.pipe(pluck('length')), this.offset$]).pipe(
map(([count, showedCount]) => count > showedCount),
shareReplay(SHARE_REPLAY_CONF)
);
constructor(
private dialog: MatDialog,
private shopsService: ShopsService,
private route: ActivatedRoute,
private router: Router,
private shopService: ShopService,
private snackBar: MatSnackBar,
private transloco: TranslocoService
) {}
constructor(private route: ActivatedRoute, private router: Router) {}
select(idx: number) {
this.shopsService.shops$.pipe(pluck(idx, 'id')).subscribe((fragment) => {
this.allShops$.pipe(pluck(idx, 'id')).subscribe((fragment) => {
this.router.navigate([], { fragment, queryParams: this.route.snapshot.queryParams });
});
}
suspend(id: string) {
this.dialog
.open(ConfirmActionDialogComponent)
.afterClosed()
.pipe(
filter((r) => r === 'confirm'),
switchMap(() => this.shopService.suspendShop(id))
)
.subscribe(
() => {
this.snackBar.open(this.transloco.translate('suspend.success', null, 'shops|scoped'), 'OK', {
duration: 3000,
});
this.shopService.reloadShops();
},
() => this.snackBar.open(this.transloco.translate('suspend.error', null, 'shops|scoped'), 'OK')
);
}
activate(id: string) {
this.dialog
.open(ConfirmActionDialogComponent)
.afterClosed()
.pipe(
filter((r) => r === 'confirm'),
switchMap(() => this.shopService.activateShop(id))
)
.subscribe(
() => {
this.snackBar.open(this.transloco.translate('activate.success', null, 'shops|scoped'), 'OK', {
duration: 3000,
});
this.shopService.reloadShops();
},
() => this.snackBar.open(this.transloco.translate('activate.error', null, 'shops|scoped'), 'OK')
);
}
showMore() {
this.showMore$.next();
}
updateShops(shops: Shop[]) {
this.allShops$.next(shops);
}
private getOffsetBySelectedPanelPosition(idx: number) {
if (idx === -1) {
return SHOPS_LIMIT;

View File

@ -8,7 +8,11 @@
</div>
</ng-container>
<ng-template #shopsPanelsList>
<dsh-shops-panels-list></dsh-shops-panels-list>
<dsh-shops-panels-list
[shops]="shops$ | async"
(suspendShop)="suspend($event)"
(activateShop)="activate($event)"
></dsh-shops-panels-list>
<div *ngIf="!(shops$ | async)?.length" class="mat-headline dsh-payouts-empty">
<dsh-empty-search-result *transloco="let t">{{ t.emptySearchResult }}</dsh-empty-search-result>
</div>

View File

@ -15,4 +15,12 @@ export class ShopsComponent {
isLoading$ = this.shopsService.isLoading$.pipe(booleanDebounceTime());
constructor(@Inject(LAYOUT_GAP) public layoutGap: string, private shopsService: ShopsService) {}
activate(id: string) {
this.shopsService.activate(id);
}
suspend(id: string) {
this.shopsService.suspend(id);
}
}

View File

@ -1,6 +1,11 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute } from '@angular/router';
import { pluck, shareReplay } from 'rxjs/operators';
import { TranslocoService } from '@ngneat/transloco';
import { filter, pluck, shareReplay, switchMap } from 'rxjs/operators';
import { ConfirmActionDialogComponent } from '@dsh/components/popups';
import { ShopService } from '../../../../api';
import { progress, SHARE_REPLAY_CONF } from '../../../../custom-operators';
@ -16,5 +21,49 @@ export class ShopsService {
isLoading$ = progress(this.route.params, this.shops$).pipe(shareReplay(SHARE_REPLAY_CONF));
constructor(private route: ActivatedRoute, private shopService: ShopService) {}
constructor(
private route: ActivatedRoute,
private shopService: ShopService,
private dialog: MatDialog,
private snackBar: MatSnackBar,
private transloco: TranslocoService
) {}
suspend(id: string) {
this.dialog
.open(ConfirmActionDialogComponent)
.afterClosed()
.pipe(
filter((r) => r === 'confirm'),
switchMap(() => this.shopService.suspendShop(id))
)
.subscribe(
() => {
this.snackBar.open(this.transloco.translate('suspend.success', null, 'shops|scoped'), 'OK', {
duration: 3000,
});
this.shopService.reloadShops();
},
() => this.snackBar.open(this.transloco.translate('suspend.error', null, 'shops|scoped'), 'OK')
);
}
activate(id: string) {
this.dialog
.open(ConfirmActionDialogComponent)
.afterClosed()
.pipe(
filter((r) => r === 'confirm'),
switchMap(() => this.shopService.activateShop(id))
)
.subscribe(
() => {
this.snackBar.open(this.transloco.translate('activate.success', null, 'shops|scoped'), 'OK', {
duration: 3000,
});
this.shopService.reloadShops();
},
() => this.snackBar.open(this.transloco.translate('activate.error', null, 'shops|scoped'), 'OK')
);
}
}

View File

@ -5,15 +5,16 @@ import { filterBattleShops, filterTestShops } from '../../../../api';
import { Shop } from '../../../../api-codegen/capi';
import { RouteEnv } from '../../../route-env';
export const filterShopsByEnv = (shops: Observable<Shop[]>) => (s: Observable<string>): Observable<Shop[]> =>
export const filterShopsByEnv = (shops$: Observable<Shop[]>) => (s: Observable<string>): Observable<Shop[]> =>
s.pipe(
switchMap((envID) => {
if (envID === RouteEnv.test) {
return shops.pipe(filterTestShops);
switch (envID) {
case RouteEnv.test:
return shops$.pipe(filterTestShops);
case RouteEnv.real:
return shops$.pipe(filterBattleShops);
default:
return throwError(`Unknown envID: ${envID}`);
}
if (envID === RouteEnv.real) {
return shops.pipe(filterBattleShops);
}
return throwError(`Unknown envID: ${envID}`);
})
);

View File

@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, Directive, HostBinding, ViewEncapsu
@Component({
selector: 'dsh-card',
styleUrls: ['card.component.scss'],
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
@ -23,7 +23,7 @@ export class CardHeaderComponent {
@Component({
selector: 'dsh-card-content',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
})
export class CardContentComponent {
@HostBinding('class.dsh-card-content') class = true;
@ -32,7 +32,7 @@ export class CardContentComponent {
@Component({
selector: 'dsh-card-actions',
exportAs: 'dshCardActions',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
})
export class CardActionsComponent {
@HostBinding('class.dsh-card-actions') class = true;

View File

@ -2,7 +2,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'dsh-dropdown-actions',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
styleUrls: ['dropdown-actions.component.scss'],
})
export class DropdownActionsComponent {}

View File

@ -2,7 +2,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'dsh-dropdown-content',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
styleUrls: ['dropdown-content.component.scss'],
})
export class DropdownContentComponent {}

View File

@ -9,7 +9,7 @@ import {
ViewContainerRef,
} from '@angular/core';
import { combineLatest, merge, of, Subscription } from 'rxjs';
import { delay, distinctUntilChanged, filter, first, map, startWith, switchMap } from 'rxjs/operators';
import { delay, distinctUntilChanged, filter, map, startWith, switchMap, take } from 'rxjs/operators';
import { coerce, smoothChangeTo } from '../../../utils';
import { ExpandPanelComponent } from './expand-panel.component';
@ -20,7 +20,7 @@ const SCROLL_TIME_MS = 500;
@Component({
selector: 'dsh-expand-panel-accordion',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
})
export class ExpandPanelAccordionComponent implements AfterViewInit {
@Output() expandedChange = new EventEmitter<number>();
@ -65,7 +65,7 @@ export class ExpandPanelAccordionComponent implements AfterViewInit {
component: components.toArray()[this.expanded],
})),
filter(({ ref, component }) => !!ref && !!component),
first(),
take(1),
delay(INIT_DELAY_MS),
switchMap(({ ref, component }) =>
combineLatest([

View File

@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, HostBinding, Input, ViewEncapsulati
@Component({
selector: 'dsh-panel-content',
template: ` <ng-content></ng-content> `,
template: `<ng-content></ng-content>`,
})
export class PanelContentComponent {
@HostBinding('class.dsh-panel-content') class = true;