FE-778: added decision type (#59)

This commit is contained in:
Alexandra Usacheva 2019-02-26 20:08:50 +03:00 committed by GitHub
parent 103b2b0247
commit 9f686d1fae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 222 additions and 87 deletions

View File

@ -0,0 +1,171 @@
import get from 'lodash-es/get';
import { Condition, Predicate, TerminalObject, TerminalRef } from '../../gen-damsel/domain';
interface PredicateInfo {
shopPartyContain: boolean;
predicateType?: PredicateType;
disabled?: boolean;
}
interface TerminalInfoGroup {
terminalIds: number[];
disabled: boolean;
predicateType: PredicateType;
}
interface FlattenTerminalInfoGroup {
terminalId: number;
disabled: boolean;
predicateType: PredicateType;
}
export enum PredicateType {
condition = 'condition',
is_not = 'is_not',
all_of = 'all_of',
any_of = 'any_of'
}
export interface TerminalInfo {
terminal: TerminalObject;
disabled: boolean;
predicateType: PredicateType;
}
function inPredicates(predicates: Predicate[], shopID: string, partyID: string): boolean {
for (const predicate of predicates) {
if (extractPredicateInfo(predicate, shopID, partyID).shopPartyContain) {
return true;
}
}
}
function inPartyCondition({ party }: Condition, shopID: string, partyID: string): boolean {
const shopIs = get(party, 'definition.shop_is');
return party.id === partyID && shopIs === shopID;
}
function isDisabled(all_of: any[]): boolean {
const constant = all_of.find(pre => pre.constant !== null);
return !!constant ? constant.constant : false;
}
function extractPredicateInfo(
{ all_of, any_of, condition, is_not }: any,
shopID: string,
partyID: string
): PredicateInfo {
if (all_of && all_of.length > 0) {
return {
shopPartyContain: inPredicates(all_of, shopID, partyID),
predicateType: PredicateType.all_of,
disabled: isDisabled(all_of)
};
}
if (any_of && any_of.length > 0) {
return {
shopPartyContain: inPredicates(any_of, shopID, partyID),
predicateType: PredicateType.any_of,
disabled: false
};
}
if (is_not && is_not.length > 0) {
return {
shopPartyContain: inPartyCondition(is_not, shopID, partyID),
predicateType: PredicateType.is_not,
disabled: true
};
}
if (condition && condition.party) {
return {
shopPartyContain: inPartyCondition(condition, shopID, partyID),
predicateType: PredicateType.condition,
disabled: false
};
}
return {
shopPartyContain: false
};
}
const extractIdsFromValue = (value: TerminalRef[]): number[] => value.map(v => v.id);
// Need TerminalDecision with if_ then_
function extractIdsFromDecisions(decisions: any[]): number[] {
return decisions.reduce((r, { then_ }) => {
if (then_.decisions) {
r = r.concat(extractIdsFromDecisions(then_.decisions));
}
if (then_.value) {
r = r.concat(extractIdsFromValue(then_.value));
}
return r;
}, []);
}
// Need TerminalSelector with Array instead Set
function extractIds({ decisions, value }: any): number[] {
if (decisions) {
return extractIdsFromDecisions(decisions);
}
if (value) {
return extractIdsFromValue(value);
}
}
const extractTerminalInfoGroup = (
decisions: any[],
shopID: string,
partyID: string
): TerminalInfoGroup[] =>
decisions.reduce((r, { if_, then_ }) => {
const { shopPartyContain, disabled, predicateType } = extractPredicateInfo(
if_,
shopID,
partyID
);
if (shopPartyContain) {
r = r.concat({
terminalIds: extractIds(then_),
disabled,
predicateType
});
}
return r;
}, []);
const flattenGroup = (group: TerminalInfoGroup[]): FlattenTerminalInfoGroup[] =>
group.reduce(
(r, { terminalIds, disabled, predicateType }) =>
(r = [
...r,
...terminalIds.map(terminalId => ({
terminalId,
disabled,
predicateType
}))
]),
[]
);
const enrichWithTerminal = (
groups: FlattenTerminalInfoGroup[],
terminalObjects: TerminalObject[]
): TerminalInfo[] =>
groups.map(group => ({
terminal: terminalObjects.find(({ ref: { id } }) => group.terminalId === id),
disabled: group.disabled,
predicateType: group.predicateType
}));
// Need TerminalDecision with if_ then_
export function extractTerminalInfo(
decisions: any[],
terminalObjects: TerminalObject[],
shopID: string,
partyID: string
): TerminalInfo[] {
const extractedGroup = extractTerminalInfoGroup(decisions, shopID, partyID);
return enrichWithTerminal(flattenGroup(extractedGroup), terminalObjects);
}

View File

@ -1,70 +0,0 @@
import { Condition, Predicate, TerminalRef } from '../../gen-damsel/domain';
import get from 'lodash-es/get';
function inPredicates(predicates: Predicate[], shopID: string, partyID: string): boolean {
for (const predicate of predicates) {
if (hasShopAndParty(predicate, shopID, partyID)) {
return true;
}
}
}
function inPartyCondition({ party }: Condition, shopID: string, partyID: string): boolean {
const shopIs = get(party, 'definition.shop_is');
return party.id === partyID && shopIs === shopID;
}
// Need Predicate in snake_case
function hasShopAndParty(
{ all_of, any_of, condition }: any,
shopID: string,
partyID: string
): boolean {
if (all_of && all_of.length > 0) {
return inPredicates(all_of, shopID, partyID);
}
if (any_of && any_of.length > 0) {
return inPredicates(any_of, shopID, partyID);
}
if (condition && condition.party) {
return inPartyCondition(condition, shopID, partyID);
}
return false;
}
function extractIdsFromValue(value: TerminalRef[]): number[] {
return value.map(v => v.id);
}
// Need TerminalDecision with if_ then_
function extractIdsFromDecisions(decisions: any[]): number[] {
return decisions.reduce((r, { then_ }) => {
if (then_.decisions) {
r = r.concat(extractIdsFromDecisions(then_.decisions));
}
if (then_.value) {
r = r.concat(extractIdsFromValue(then_.value));
}
return r;
}, []);
}
// Need TerminalSelector with Array instead Set
function extractIds({ decisions, value }: any): number[] {
if (decisions) {
return extractIdsFromDecisions(decisions);
}
if (value) {
return extractIdsFromValue(value);
}
}
// Need TerminalDecision with if_ then_
export function findTerminalIds(decisions: any[], shopID: string, partyID: string): number[] {
return decisions.reduce((r, { if_, then_ }) => {
if (hasShopAndParty(if_, shopID, partyID)) {
r = r.concat(extractIds(then_));
}
return r;
}, []);
}

View File

@ -0,0 +1,10 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'ccIsActive'
})
export class IsActivePipe implements PipeTransform {
public transform(input: boolean): string {
return input ? 'Active' : 'Inactive';
}
}

View File

@ -5,10 +5,14 @@
<mat-panel-description> {{ info?.provider.data.description }} </mat-panel-description>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<mat-list *ngIf="info.terminals">
<mat-list *ngIf="info.terminalInfos">
<h3 mat-subheader>Terminals</h3>
<mat-list-item *ngFor="let terminal of info.terminals">
<cc-terminal [terminal]="terminal"></cc-terminal>
<mat-list-item *ngFor="let terminalInfo of info.terminalInfos">
<cc-terminal
[terminal]="terminalInfo.terminal"
[disabled]="terminalInfo.disabled"
[predicateType]="terminalInfo.predicateType"
></cc-terminal>
</mat-list-item>
</mat-list>
</ng-template>

View File

@ -0,0 +1,3 @@
cc-terminal {
width: 100%;
}

View File

@ -4,7 +4,8 @@ import { ProviderInfo } from '../shop-details.service';
@Component({
selector: 'cc-provider',
templateUrl: 'provider.component.html'
templateUrl: 'provider.component.html',
styleUrls: ['provider.component.scss']
})
export class ProviderComponent {
@Input() providerInfo: ProviderInfo[];

View File

@ -3,6 +3,7 @@ import {
MatButtonModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatDialogModule,
MatExpansionModule,
MatFormFieldModule,
@ -32,6 +33,7 @@ import { TerminalsTableComponent } from './add-provider/select-terminal/terminal
import { CreateTerminalFormComponent } from './add-provider/select-terminal/create-terminal-form/create-terminal-form.component';
import { SelectTerminalComponent } from './add-provider/select-terminal/select-terminal.component';
import { SelectProviderComponent } from './add-provider/select-provider/select-provider.component';
import { IsActivePipe } from './is-active.pipe';
@NgModule({
imports: [
@ -53,7 +55,8 @@ import { SelectProviderComponent } from './add-provider/select-provider/select-p
MatInputModule,
MatTabsModule,
MatIconModule,
MatProgressBarModule
MatProgressBarModule,
MatChipsModule
],
declarations: [
ShopDetailsComponent,
@ -66,7 +69,8 @@ import { SelectProviderComponent } from './add-provider/select-provider/select-p
TerminalsTableComponent,
CreateTerminalFormComponent,
SelectProviderComponent,
SelectTerminalComponent
SelectTerminalComponent,
IsActivePipe
],
entryComponents: [AddProviderComponent]
})

View File

@ -3,15 +3,14 @@ import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import get from 'lodash-es/get';
import { Shop } from '../../gen-damsel/domain';
import { ProviderObject, TerminalObject } from '../../gen-damsel/domain';
import { findTerminalIds } from './find-terminal-ids';
import { ProviderObject, Shop, TerminalObject } from '../../gen-damsel/domain';
import { extractTerminalInfo, TerminalInfo } from './extract-terminal-info';
import { PartyService } from '../party.service';
import { DomainTypedManager } from '../../thrift';
export interface ProviderInfo {
provider: ProviderObject;
terminals: TerminalObject[];
terminalInfos: TerminalInfo[];
}
export interface Payload {
@ -47,17 +46,15 @@ export class ShopDetailsService {
if (!decisions) {
return r;
}
const ids = findTerminalIds(decisions, shopID, partyID);
if (ids.length === 0) {
const infos = extractTerminalInfo(decisions, terminalObjects, shopID, partyID);
if (infos.length === 0) {
return r;
}
return [
...r,
{
provider,
terminals: ids.map(terminalId =>
terminalObjects.find(({ ref: { id } }) => id === terminalId)
)
terminalInfos: infos
}
];
}, []);

View File

@ -1 +1,9 @@
<span *ngIf="terminal"> {{ terminal.data.name }} - {{ terminal.data.description }} </span>
<div fxLayout="row" fxLayoutAlign="space-between center">
<div>
{{ terminal.data.name }} - {{ terminal.data.description }}
<span class="predicate-type">{{ predicateType }}</span>
</div>
<mat-chip-list>
<mat-chip [selected]="!disabled">{{ !disabled | ccIsActive }}</mat-chip>
</mat-chip-list>
</div>

View File

@ -0,0 +1,3 @@
.predicate-type {
color: #bbbbbb;
}

View File

@ -1,11 +1,15 @@
import { Component, Input } from '@angular/core';
import { TerminalObject } from '../../../gen-damsel/domain';
import { PredicateType } from '../extract-terminal-info';
@Component({
selector: 'cc-terminal',
templateUrl: 'terminal.component.html'
templateUrl: 'terminal.component.html',
styleUrls: ['terminal.component.scss']
})
export class TerminalComponent {
@Input() terminal: TerminalObject;
@Input() disabled: boolean;
@Input() predicateType: PredicateType;
}