Skip to content

Commit

Permalink
fix(backend): use new backend for orgdiagram for valid results (#664)
Browse files Browse the repository at this point in the history
* fix the orgdiagramm bug

* use the new database in the organigramm

* Update Phonebook.Frontend/src/app/services/api/organigram.service.ts

Co-authored-by: DanielHabenicht <[email protected]>

* test(unit): fix fontend unit tests

* fix business ctor

* Update Phonebook.preview.yml for Azure Pipelines

Co-authored-by: DanielHabenicht <[email protected]>
  • Loading branch information
paule96 and DanielHabenicht authored May 17, 2020
1 parent 21d8120 commit 73d6ae2
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 122 deletions.
40 changes: 32 additions & 8 deletions .azure/pipelines/Phonebook.preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ pr:
variables:
image_repo: tsystemsmms
image_namespace: phonebook-build
image_tag: pr-$(System.PullRequest.PullRequestNumber)
image_tag_frontend: pr-$(System.PullRequest.PullRequestNumber)
image_tag_source_peoplesoft: pr-$(System.PullRequest.PullRequestNumber)-peoplesoft
helm_artifact_name: HelmPhonebookPackage

jobs:
Expand All @@ -19,23 +20,46 @@ jobs:
inputs:
version: '12.x'

- script: node version.js $(image_tag) $(Build.SourceVersion) $(Build.SourceVersion)
- script: node version.js $(image_tag_frontend) $(Build.SourceVersion) $(Build.SourceVersion)
displayName: 'Write Version Number'
workingDirectory: 'Phonebook.Frontend/'

- script: docker build -t $(image_repo)/$(image_namespace):$(image_tag) .
- script: docker build -t $(image_repo)/$(image_namespace):$(image_tag_frontend) .
displayName: 'Build Image'
workingDirectory: 'Phonebook.Frontend/'

- script: |
docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD
docker push $(image_repo)/$(image_namespace):$(image_tag)
docker push $(image_repo)/$(image_namespace):$(image_tag_frontend)
workingDirectory: 'Phonebook.Frontend/'
displayName: 'Push Image'
env:
DOCKER_REGISTRY_PASSWORD: $(DOCKER_REGISTRY_PASSWORD)
DOCKER_REGISTRY_USER: $(DOCKER_REGISTRY_USER)
- job: build_phonebook_source_peoplesoft
displayName: 'Phonebook Source Peoplesoft'
pool:
vmImage: 'ubuntu-16.04'
steps:
- task: UseNode@1
inputs:
version: '12.x'


- script: docker build -t $(image_repo)/$(image_namespace):$(image_tag_source_peoplesoft) .
displayName: 'Build Image'
workingDirectory: 'Phonebook.Source.PeopleSoft/'

- script: |
docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD
docker push $(image_repo)/$(image_namespace):$(image_tag_source_peoplesoft)
workingDirectory: 'Phonebook.Source.PeopleSoft/'
displayName: 'Push Image'
env:
DOCKER_REGISTRY_PASSWORD: $(DOCKER_REGISTRY_PASSWORD)
DOCKER_REGISTRY_USER: $(DOCKER_REGISTRY_USER)
- job: build_phonebook_helm
displayName: Phonebook Helm Chart
pool:
Expand Down Expand Up @@ -63,7 +87,7 @@ jobs:
pool:
vmImage: 'ubuntu-16.04'
variables:
namespace: $(image_tag)
namespace: $(image_tag_frontend)
steps:
- download: current
artifact: $(helm_artifact_name)
Expand Down Expand Up @@ -98,7 +122,7 @@ jobs:
chartType: FilePath
chartPath: '$(Pipeline.Workspace)/$(helm_artifact_name)/phonebook-0.1.0.tgz'
releaseName: phonebook-$(namespace)
overrideValues: 'frontend.image.tag=$(image_tag),frontend.image.repository=$(image_repo),frontend.image.name=$(image_namespace),traefik.enabled=false,host=$(image_tag).demo-phonebook.me'
overrideValues: 'frontend.image.tag=$(image_tag_frontend),frontend.image.repository=$(image_repo),frontend.image.name=$(image_namespace),source.peoplesoft.image.tag=$(image_tag_source_peoplesoft),source.peoplesoft.image.name=$(image_namespace),traefik.enabled=false,host=$(image_tag_frontend).demo-phonebook.me'
valueFile: 'demo/values.yml'
recreate: true
tillerNamespace: kube-system
Expand Down Expand Up @@ -128,7 +152,7 @@ jobs:
}
body: |
{
"body": "Preview Environment ready at https://$(image_tag).demo-phonebook.me"
"body": "Preview Environment ready at https://$(image_tag_frontend).demo-phonebook.me"
}
urlSuffix: 'repos/T-Systems-MMS/phonebook/issues/$(System.PullRequest.PullRequestNumber)/comments'
waitForCompletion: 'false'
Expand All @@ -153,7 +177,7 @@ jobs:
pool:
vmImage: 'ubuntu-16.04'
variables:
namespace: $(image_tag)
namespace: $(image_tag_frontend)
steps:
- checkout: none
- task: HelmInstaller@1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const routes: Routes = [
{ path: ':first/:second/:third', component: OrganigramComponent },
{ path: ':first/:second/:third/:fourth', component: OrganigramComponent },
{ path: ':first/:second/:third/:fourth/:fifth', component: OrganigramComponent },
{ path: ':first/:second/:third/:fourth/:fifth/:sixth', component: OrganigramComponent },
];

@NgModule({
Expand Down
26 changes: 13 additions & 13 deletions Phonebook.Frontend/src/app/modules/table/table-logic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
new Person(
PersonStatus.Interner_Mitarbeiter,
Expand All @@ -36,7 +36,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
];
expect(
Expand All @@ -55,7 +55,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
new Person(
PersonStatus.Interner_Mitarbeiter,
Expand All @@ -67,7 +67,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
]);
});
Expand All @@ -83,7 +83,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
new Person(
PersonStatus.Interner_Mitarbeiter,
Expand All @@ -95,7 +95,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
];

Expand All @@ -115,7 +115,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
new Person(
PersonStatus.Interner_Mitarbeiter,
Expand All @@ -127,7 +127,7 @@ describe('Table Logic - Sort', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
]);
});
Expand All @@ -146,7 +146,7 @@ describe('Table Logic - Filter', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
];
expect(
Expand All @@ -162,7 +162,7 @@ describe('Table Logic - Filter', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
]);
});
Expand All @@ -179,7 +179,7 @@ describe('Table Logic - Filter', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
];
expect(
Expand All @@ -199,7 +199,7 @@ describe('Table Logic - Filter', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
];
expect(
Expand All @@ -219,7 +219,7 @@ describe('Table Logic - Filter', () => {
false,
new Contacts('', '', '', '', new Messenger('', 0)),
new Location(new City('', ''), []),
new Business([], [], [], [], [], [], '')
new Business(null, [], [], [], [], [], [], '')
),
]);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { inject, TestBed } from '@angular/core/testing';
import { OrganigramService } from './organigram.service';
import { PersonService } from './person.service';
import { HttpClient } from '@angular/common/http';

describe('OrganigramService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [OrganigramService, { provide: PersonService, useValue: null }],
providers: [
OrganigramService,
{ provide: PersonService, useValue: null },
{ provide: HttpClient, useValue: null },
],
});
});

Expand Down
135 changes: 77 additions & 58 deletions Phonebook.Frontend/src/app/services/api/organigram.service.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,62 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Observable, forkJoin, of } from 'rxjs';
import { map, flatMap, publishReplay, refCount } from 'rxjs/operators';
import { Person } from 'src/app/shared/models';
import { PersonService } from './person.service';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class OrganigramService {
constructor(private personService: PersonService) {}

constructor(private http: HttpClient, private personService: PersonService) {}
public organigram: Observable<UnitTreeNode[]>;
public getOrganigram(): Observable<UnitTreeNode[]> {
return this.personService.getAll().pipe(
map((users) => {
const tree: UnitTreeNode[] = [];
users.forEach((person) => {
if (person.Business.ShortOrgUnit.length === 0) {
return;
}
this.findNodeForPerson(person, tree, 0);
});
return tree;
})
);
}

/**
* Finds the Person's Node in the Hierarchical Structure of Units (generates the Units along its way.)
* @param person The person for whom you like to find the node
* @param nodeChilds The Childs of the node your are currently searching in.
* @param depth The depth of the Tree (to map the Persons Array of Units to the Tree structure)
*/
public findNodeForPerson(person: Person, nodeChilds: UnitTreeNode[], depth: number) {
const firstnode = nodeChilds.find((node) => {
return node.id === person.Business.ShortOrgUnit[depth];
});
if (firstnode === undefined) {
const newNode = new UnitTreeNode(
person.Business.ShortOrgUnit[depth],
person.Business.OrgUnit[depth],
depth
);
if (depth === person.Business.ShortOrgUnit.length - 1) {
this.pushToSpecificGroup(newNode, person);
} else if (person.Business.ShortOrgUnit.length - 1 > depth) {
this.findNodeForPerson(person, newNode.children, depth + 1);
}
nodeChilds.push(newNode);
} else {
if (depth === person.Business.ShortOrgUnit.length - 1) {
this.pushToSpecificGroup(firstnode, person);
return;
} else {
this.findNodeForPerson(person, firstnode.children, depth + 1);
}
if (this.organigram != null) {
return this.organigram;
}
this.organigram = this.http.get<OrgUnit[]>('/api/OrgUnit').pipe(
flatMap((d) => this.ConvertOrgUnitsToUnitTree(d)),
publishReplay(1), // this tells Rx to cache the latest emitted
refCount()
);
return this.organigram;
}

public pushToSpecificGroup(node: UnitTreeNode, person: Person) {
if (person.isLearner()) {
node.learners.push(person);
} else if (person.isSupervisor()) {
node.supervisors.push(person);
} else if (person.isAssistent()) {
node.assistents.push(person);
} else {
node.employees.push(person);
}
private ConvertOrgUnitsToUnitTree(
orgUnits: OrgUnit[],
depth: number = 0
): Observable<UnitTreeNode[]> {
return forkJoin(
orgUnits.map((o) => {
var TaShortNames = o.OrgUnitToFunctions.filter((f) => f.RoleName == 'TA').map(
(t) => t.Person.ShortName
);
return forkJoin(
o.ChildOrgUnits == null || o.ChildOrgUnits.length == 0
? of([])
: this.ConvertOrgUnitsToUnitTree(o.ChildOrgUnits, depth + 1),
o.HeadOfOrgUnit == null
? of(null)
: this.personService.getById(o.HeadOfOrgUnit.ShortName),
TaShortNames.length == 0
? of([])
: forkJoin(TaShortNames.map((shortName) => this.personService.getById(shortName))),
o.ShortName == null ? of([]) : this.personService.getByOrgUnit(o.ShortName)
).pipe(
map(([childs, headofOrgUnit, assistents, members]) => {
var tree = new UnitTreeNode(
o.ShortName == null ? '' : o.ShortName,
o.Name == null ? '' : o.Name,
depth,
o.ChildOrgUnits == null ? [] : childs,
headofOrgUnit == null ? [] : [headofOrgUnit],
assistents.filter((a) => a != null) as Person[],
members.filter((p) => p.isLearner() == false),
members.filter((p) => p.isLearner())
);
return tree;
})
);
})
);
}
}

Expand Down Expand Up @@ -97,3 +89,30 @@ export class UnitTreeNode {
this.learners = learners;
}
}

class OrgUnit {
public Id: number;

public Name?: string;

public ShortName?: string;

public ParentId?: number;
public Parent?: OrgUnit;
public ChildOrgUnits?: OrgUnit[];

public HeadOfOrgUnitId?: number;

public HeadOfOrgUnit?: {
ShortName: string;
};

public CostCenter?: string;
public OrgUnitToFunctions: {
PersonId?: number;
Person: {
ShortName: string;
};
RoleName: string;
}[];
}
Loading

0 comments on commit 73d6ae2

Please sign in to comment.