-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #66 from ducktordanny/feat/second-phase-results-ui
Feat: Second phase of transportation problem - UI side
- Loading branch information
Showing
49 changed files
with
1,305 additions
and
558 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,5 @@ Thumbs.db | |
/temp | ||
/resources | ||
.vercel | ||
|
||
.angular |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 1 addition & 27 deletions
28
apps/backend/src/app/controllers/transport-problem/utils/tests/transport.util.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
apps/frontend/src/app/components/info-card/info-card.style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
apps/frontend/src/app/pages/assignment-problem/assignment-problem.style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
@import '../../styles/variables/colors'; | ||
@import 'libs/shared/styles/colors'; | ||
|
||
:host { | ||
overflow-x: hidden; | ||
|
91 changes: 91 additions & 0 deletions
91
...es/transport-problem/+first-phase-result-input/first-phase-result-input.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import {HttpClientModule} from '@angular/common/http'; | ||
import {ComponentFixture, TestBed} from '@angular/core/testing'; | ||
import {MatStepperModule} from '@angular/material/stepper'; | ||
import {NoopAnimationsModule} from '@angular/platform-browser/animations'; | ||
|
||
import { | ||
InputTableModule, | ||
InputTableService, | ||
TableModule, | ||
} from '@opres/ui/tables'; | ||
import {TranslateModule} from '@ngx-translate/core'; | ||
|
||
import {AllTabModule} from '../+tabs/all-tab/all.tab.module'; | ||
import {TabsModule} from '../+tabs/tabs.module'; | ||
import {TransportProblemService} from '../transport-problem.service'; | ||
|
||
import {FirstPhaseResultInputComponent} from './first-phase-result-input.component'; | ||
|
||
describe('FirstPhaseResultInputComponent', () => { | ||
let fixture: ComponentFixture<FirstPhaseResultInputComponent>; | ||
let component: FirstPhaseResultInputComponent; | ||
let inputTableService: InputTableService; | ||
const firstStepFormGroupMock = { | ||
shops: 4, | ||
storages: 4, | ||
}; | ||
const costsMock = [ | ||
{'0': 8, '1': 7, '2': 3, '3': 2}, | ||
{'0': 1, '1': 4, '2': 2, '3': 5}, | ||
{'0': 2, '1': 3, '2': 4, '3': 7}, | ||
{'0': 1, '1': 1, '2': 4, '3': 4}, | ||
]; | ||
const transportationsMock = [ | ||
{'0': null, '1': null, '2': null, '3': 15}, | ||
{'0': 8, '1': null, '2': 35, '3': null}, | ||
{'0': 10, '1': 13, '2': null, '3': 5}, | ||
{'0': null, '1': 19, '2': null, '3': null}, | ||
]; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [FirstPhaseResultInputComponent], | ||
imports: [ | ||
AllTabModule, | ||
HttpClientModule, | ||
InputTableModule, | ||
MatStepperModule, | ||
NoopAnimationsModule, | ||
TableModule, | ||
TabsModule, | ||
TranslateModule.forRoot(), | ||
], | ||
providers: [TransportProblemService], | ||
}); | ||
|
||
fixture = TestBed.createComponent(FirstPhaseResultInputComponent); | ||
component = fixture.componentInstance; | ||
inputTableService = TestBed.inject(InputTableService); | ||
}); | ||
|
||
it('should be created', () => | ||
expect(component).toBeInstanceOf(FirstPhaseResultInputComponent)); | ||
|
||
it('should check default values', (done) => { | ||
expect(component.firstStepFormGroup.getRawValue()).toEqual( | ||
firstStepFormGroupMock, | ||
); | ||
expect(component.secondStepFormGroup.getRawValue()).toEqual({}); | ||
expect(component.costs$.getValue()).toEqual(costsMock); | ||
expect(component.transportations$.getValue()).toEqual(transportationsMock); | ||
component.isLoading$.subscribe((loading: boolean) => | ||
expect(loading).toEqual(false), | ||
); | ||
done(); | ||
}); | ||
|
||
it('should change values of tables', () => { | ||
component.onTransportationsChange([]); | ||
expect(component.transportations$.getValue()).toEqual([]); | ||
component.onCostsChange([]); | ||
expect(component.costs$.getValue()).toEqual([]); | ||
}); | ||
|
||
it('should clear tables', () => { | ||
const tableClearSpy = jest.spyOn(inputTableService, 'clear'); | ||
component.onTransportationsClear(); | ||
expect(tableClearSpy).toHaveBeenCalledWith('transportations'); | ||
component.onCostsClear(); | ||
expect(tableClearSpy).toHaveBeenCalledWith('costs'); | ||
}); | ||
}); |
121 changes: 121 additions & 0 deletions
121
...p/pages/transport-problem/+first-phase-result-input/first-phase-result-input.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import { | ||
ChangeDetectionStrategy, | ||
Component, | ||
EventEmitter, | ||
Output, | ||
} from '@angular/core'; | ||
import {FormControl, FormGroup} from '@angular/forms'; | ||
|
||
import {Table, TransportTable} from '@opres/shared/types'; | ||
import {InputTableService} from '@opres/ui/tables'; | ||
import {LanguageSwitcherService} from '@frontend/components/layout/language-switcher/language-switcher.service'; | ||
import {LoadingHandlerService} from '@frontend/services/loading-handler.service'; | ||
import {forEach, mapValues} from 'lodash'; | ||
import {BehaviorSubject} from 'rxjs'; | ||
|
||
import { | ||
transportProblemCacheBuster$, | ||
TransportProblemService, | ||
} from '../transport-problem.service'; | ||
|
||
@Component({ | ||
selector: 'first-phase-result-input', | ||
templateUrl: './first-phase-result-input.template.html', | ||
styleUrls: [ | ||
'../+tabs/tabs.style.scss', | ||
'./first-phase-result-input.style.scss', | ||
], | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
}) | ||
export class FirstPhaseResultInputComponent { | ||
@Output() public calculate = new EventEmitter<TransportTable>(); | ||
public firstStepFormGroup: FormGroup; | ||
public secondStepFormGroup: FormGroup; | ||
public costs$ = new BehaviorSubject<Table>([ | ||
{'0': 8, '1': 7, '2': 3, '3': 2}, | ||
{'0': 1, '1': 4, '2': 2, '3': 5}, | ||
{'0': 2, '1': 3, '2': 4, '3': 7}, | ||
{'0': 1, '1': 1, '2': 4, '3': 4}, | ||
]); | ||
public transportations$ = new BehaviorSubject<Table>([ | ||
{'0': null, '1': null, '2': null, '3': 15}, | ||
{'0': 8, '1': null, '2': 35, '3': null}, | ||
{'0': 10, '1': 13, '2': null, '3': 5}, | ||
{'0': null, '1': 19, '2': null, '3': null}, | ||
]); | ||
public isLoading$ = this.loadingHandler.isLoading; | ||
|
||
constructor( | ||
private transportProblemService: TransportProblemService, | ||
private languageSwitcherService: LanguageSwitcherService, | ||
private inputTableService: InputTableService, | ||
private loadingHandler: LoadingHandlerService, | ||
) { | ||
this.firstStepFormGroup = new FormGroup({ | ||
shops: new FormControl(4, transportProblemService.tableSizeValidators), | ||
storages: new FormControl(4, transportProblemService.tableSizeValidators), | ||
}); | ||
this.secondStepFormGroup = new FormGroup({}); | ||
} | ||
|
||
public onCostsChange(table: Table): void { | ||
this.costs$.next(table); | ||
transportProblemCacheBuster$.next(); | ||
this.validateCostsTable(); | ||
} | ||
|
||
public onTransportationsChange(table: Table): void { | ||
this.transportations$.next(table); | ||
transportProblemCacheBuster$.next(); | ||
this.validateTransportationsTable(); | ||
} | ||
|
||
public onCostsClear(): void { | ||
this.inputTableService.clear('costs'); | ||
} | ||
|
||
public onTransportationsClear(): void { | ||
this.inputTableService.clear('transportations'); | ||
} | ||
|
||
public onCalculate(): void { | ||
this.calculate.emit(this.getTransportTableFromCurrentInput()); | ||
} | ||
|
||
private getTransportTableFromCurrentInput(): TransportTable { | ||
const transportations = this.transportations$.getValue(); | ||
return this.costs$.getValue().map((row, index) => { | ||
return mapValues(row, (cost, key) => ({ | ||
cost: cost as number, | ||
transported: transportations[index][key] || undefined, | ||
})); | ||
}); | ||
} | ||
|
||
private validateCostsTable(): void { | ||
const costs = this.costs$.getValue(); | ||
let hasNullCost = false; | ||
|
||
for (const row of costs) | ||
forEach(row, (cost) => { | ||
if (cost === null || cost === undefined) hasNullCost = true; | ||
}); | ||
|
||
if (hasNullCost) this.firstStepFormGroup.setErrors({nullCost: true}); | ||
else this.firstStepFormGroup.setErrors(null); | ||
} | ||
|
||
private validateTransportationsTable(): void { | ||
const transportations = this.transportations$.getValue(); | ||
let hasTransported = false; | ||
|
||
for (const row of transportations) | ||
forEach(row, (transport) => { | ||
if (transport) hasTransported = true; | ||
}); | ||
|
||
if (!hasTransported) | ||
this.secondStepFormGroup.setErrors({noTransport: true}); | ||
else this.secondStepFormGroup.setErrors(null); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
.../app/pages/transport-problem/+first-phase-result-input/first-phase-result-input.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {NgModule} from '@angular/core'; | ||
import {MatStepperModule} from '@angular/material/stepper'; | ||
|
||
import {InputTableModule, TableModule} from '@opres/ui/tables'; | ||
|
||
import {TabsModule} from '../+tabs/tabs.module'; | ||
|
||
import {FirstPhaseResultInputComponent} from './first-phase-result-input.component'; | ||
|
||
@NgModule({ | ||
declarations: [FirstPhaseResultInputComponent], | ||
imports: [InputTableModule, MatStepperModule, TableModule, TabsModule], | ||
exports: [FirstPhaseResultInputComponent], | ||
}) | ||
export class FirstPhaseResultInputModule {} |
10 changes: 10 additions & 0 deletions
10
...app/pages/transport-problem/+first-phase-result-input/first-phase-result-input.style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
:host { | ||
::ng-deep.mat-horizontal-content-container { | ||
padding: 0; | ||
} | ||
|
||
.table-wrapper { | ||
overflow-x: auto; | ||
padding: 8px; | ||
} | ||
} |
Oops, something went wrong.