Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/refactor frontend #449

Merged
merged 63 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
2cbe29b
create sidepanel component and add additional route to routing module
Vakmeth Oct 9, 2023
2474366
format new generated component
Vakmeth Oct 9, 2023
73fb77b
create refresh-data service
Vakmeth Oct 9, 2023
bd92118
implement objective detail in sidepanel and delete old drawer component
Vakmeth Oct 9, 2023
3f3c720
format files
Vakmeth Oct 9, 2023
7baec9e
implement key-result-detail in new sidepanel
Vakmeth Oct 10, 2023
4f1979e
implement sidepanel backdrop and focus trap
Vakmeth Oct 10, 2023
a1bc73c
use cdkoverlay as sidebar, add focustrap backdrop
kcinay055679 Oct 10, 2023
a39599f
disable scrolling with css overflow class
Vakmeth Oct 10, 2023
9f3d0ed
delete unnecessary tags in side panel
Vakmeth Oct 12, 2023
347eb64
implement creating keyresults over sidepanel
Vakmeth Oct 12, 2023
760d860
subscribe in sidepanel already to id and use replaysubject to create …
Vakmeth Oct 12, 2023
6bbbaed
optimize imports
Vakmeth Oct 12, 2023
325dd69
use behaviour subject instead of replay subject
Vakmeth Oct 12, 2023
d17aa40
resolve requested changes
Vakmeth Oct 12, 2023
be0e2bd
optimize imports
Vakmeth Oct 12, 2023
ad38fc7
implement adding objectives by using subject in overview.ts
Vakmeth Oct 12, 2023
21d8a5f
use refresh-data-service to update overview in objective component
Vakmeth Oct 12, 2023
eb1e9c1
fix creating keyresults after objective created
Vakmeth Oct 13, 2023
d63cd62
delete use of router-service in objective component
Vakmeth Oct 13, 2023
489483a
delete unused tests out of project
Vakmeth Oct 13, 2023
607a360
format test file of app-component
Vakmeth Oct 13, 2023
5956d17
rework sidepanel design
kcinay055679 Oct 12, 2023
ca817de
change width of sidepanel
kcinay055679 Oct 12, 2023
3c8511e
clean up buttons fix styling of keyresult detail
kcinay055679 Oct 12, 2023
f335bfd
add confidence and scroring components
kcinay055679 Oct 12, 2023
09a2dd3
--amend
kcinay055679 Oct 12, 2023
be25ff8
use behaviorsubject in keyresultDetailcomponent
kcinay055679 Oct 12, 2023
cb7b277
rework dialog flow keyresult
kcinay055679 Oct 13, 2023
8fa2c48
fix delete button on keyresult form, add missing close button
kcinay055679 Oct 13, 2023
120fee0
fix checkin history and related edit+ delete
kcinay055679 Oct 13, 2023
1fbaac3
remove console.log
kcinay055679 Oct 13, 2023
481aded
remove service from app component
Vakmeth Oct 13, 2023
22fb2a3
remove notifier-service from error-interceptor
Vakmeth Oct 13, 2023
47dddf4
delete notifier service and optimize imports in app module
Vakmeth Oct 13, 2023
5ca85b6
remove unnecessary route-service
Vakmeth Oct 13, 2023
8e3cf5e
move scoring component to custom folder
Vakmeth Oct 13, 2023
9d9a163
fix test issues by adding necessary imports and mocks
Vakmeth Oct 13, 2023
95f3345
rename test
Vakmeth Oct 13, 2023
b6294cd
add spinners
kcinay055679 Oct 13, 2023
b01a71b
--ammend
kcinay055679 Oct 13, 2023
2fc6ced
implement feedback
kcinay055679 Oct 13, 2023
8122767
clean up html
kcinay055679 Oct 13, 2023
b2f8109
fix styling and clean up styles.scss
kcinay055679 Oct 13, 2023
1d69f5e
fix focustrap
kcinay055679 Oct 13, 2023
66e5881
fix tests
kcinay055679 Oct 13, 2023
224ba1f
remove useless focustrap tag
kcinay055679 Oct 13, 2023
2c2f9e8
align mat-icon-close with sidepanel title
Vakmeth Oct 16, 2023
21dc55c
add autofocus on primary button
Vakmeth Oct 16, 2023
56019f5
implement sidepanel animation when opened
Vakmeth Oct 16, 2023
ae5b472
align button in objective detail
Vakmeth Oct 16, 2023
bbe76ff
adjust alignmnet of keyresult detail and ordinal boxes
Vakmeth Oct 16, 2023
314bf0c
adjust confidence on key resutl detail
Vakmeth Oct 16, 2023
0a4c8b9
remove all presets
Vakmeth Oct 16, 2023
7d3bd25
rename subject in team component
Vakmeth Oct 16, 2023
1688803
delete unnecessary information when owner or changeinfo does not exist
Vakmeth Oct 16, 2023
eb7b42f
delete label of unit in scoring of metric keyresult to fix alignment
Vakmeth Oct 16, 2023
704dfd9
fix styling and delete usage of notiferService
Vakmeth Oct 16, 2023
e3c5073
format files after rebase
Vakmeth Oct 16, 2023
7d8bf08
optimize imports in testfile and fix tests by setting overviewentitie…
Vakmeth Oct 16, 2023
34dcfdf
rename subject in objective component
Vakmeth Oct 16, 2023
3662997
restyle three-dot-menu to be at top of objective
Vakmeth Oct 16, 2023
5b5ed79
style three-dot-menu with different color and aligned with objective …
Vakmeth Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ActivatedRouteSnapshot, ResolveFn, RouterModule, Routes } from '@angular/router';
import { OverviewComponent } from './overview/overview.component';
import { ObjectiveDetailComponent } from './objective-detail/objective-detail.component';
import { KeyresultDetailComponent } from './keyresult-detail/keyresult-detail.component';
import { EMPTY, of } from 'rxjs';
import { SidepanelComponent } from './shared/custom/sidepanel/sidepanel.component';

/**
* Resolver for get the id from url like `/objective/42` or `/keyresult/42`.
*/
export const getIdFromPathResolver: ResolveFn<number> = (route: ActivatedRouteSnapshot) => {
try {
let id = Number.parseInt(route.url[1].path);
return of(id);
} catch (error) {
console.error('Can not get id from URL:', error);
return EMPTY;
}
};

const routes: Routes = [
{
path: '',
component: OverviewComponent,
children: [
{ path: 'objective/:id', component: ObjectiveDetailComponent, pathMatch: 'full' },
{ path: 'keyresult/:id', component: KeyresultDetailComponent, pathMatch: 'full' },
{
path: 'objective/:id',
component: SidepanelComponent,
resolve: { id: getIdFromPathResolver },
data: { type: 'Objective' },
},
{
path: 'keyresult/:id',
component: SidepanelComponent,
resolve: { id: getIdFromPathResolver },
data: { type: 'KeyResult' },
},
],
},
{ path: '**', redirectTo: '', pathMatch: 'full' },
Expand Down
29 changes: 4 additions & 25 deletions frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,7 @@
<div>
<app-application-top-bar></app-application-top-bar>

<mat-drawer-container hasBackdrop="true">
<mat-drawer
(closed)="enableScrolling()"
(closedStart)="closeDrawer()"
(keydown.enter)="closeDrawer()"
(keydown.escape)="closeDrawer()"
(keydown.space)="closeDrawer()"
[opened]="!!sidenavContentInformation"
class="mt-5 position-fixed p-3 col-sm-12 col-md-5"
data-test-id="mat-drawer"
mode="over"
position="end"
>
<app-drawer-content
*ngIf="sidenavContentInformation"
[drawerContent]="sidenavContentInformation!"
></app-drawer-content>
</mat-drawer>
<mat-drawer-content>
<app-application-banner id="bannerComponent"></app-application-banner>
<div class="mt-header-height"></div>
<router-outlet></router-outlet>
</mat-drawer-content>
</mat-drawer-container>
<app-application-banner id="bannerComponent"></app-application-banner>
<div class="mt-header-height">
<router-outlet></router-outlet>
</div>
</div>
57 changes: 2 additions & 55 deletions frontend/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingHarness, RouterTestingModule } from '@angular/router/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { CUSTOM_ELEMENTS_SCHEMA, NgZone } from '@angular/core';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { TranslateTestingModule } from 'ngx-translate-testing';
import { AuthConfig, OAuthModule, OAuthService } from 'angular-oauth2-oidc';
import { MatDrawerContainerHarness, MatDrawerHarness } from '@angular/material/sidenav/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
// @ts-ignore
import * as de from '../assets/i18n/de.json';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { By } from '@angular/platform-browser';
import { MatSidenavModule } from '@angular/material/sidenav';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { NavigationEnd, Routes } from '@angular/router';
Expand Down Expand Up @@ -82,55 +80,4 @@ describe('AppComponent', () => {
test('should create the app', () => {
expect(component).toBeTruthy();
});

describe('Mat-drawer', () => {
test('should open and close mat-drawer', async () => {
await loader.getHarness(MatDrawerContainerHarness).then(async (drawerContainer: MatDrawerContainerHarness) => {
drawerContainer.getDrawers().then(async (drawers: MatDrawerHarness[]) => {
const drawer: MatDrawerHarness = drawers[0];
component.openDrawer();
fixture.detectChanges();
expect(await drawer.isOpen()).toEqual(true);
component.closeDrawer();
fixture.detectChanges();
expect(await drawer.isOpen()).toEqual(false);
});
});
});

test.each([
['keydown.enter', false],
['keydown.space', false],
['keydown.escape', false],
['', true],
])('close on keyPress', async (event: string, isOpen: boolean) => {
await loader.getHarness(MatDrawerContainerHarness).then(async (drawerContainer) => {
drawerContainer.getDrawers().then(async (drawers) => {
let drawer = drawers[0];
component.openDrawer();

expect(await drawer.isOpen()).toEqual(true);
fixture.debugElement.triggerEventHandler(event, { bubbles: true });
fixture.detectChanges();

expect(await drawer.isOpen()).toEqual(isOpen);
});
});
});
});

describe('routing', () => {
test('should trigger openDrawer functionality if right path', async () => {
const ngZone: NgZone = TestBed.inject(NgZone);
const routerTest = await RouterTestingHarness.create();

await ngZone.run(async () => {
await routerTest.navigateByUrl('/objective/3');
});

fixture.detectChanges();
const content = fixture.debugElement.query(By.css('app-drawer-content'));
expect(content).toBeTruthy();
});
});
});
58 changes: 4 additions & 54 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, map, Observable } from 'rxjs';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { map } from 'rxjs';
import { OAuthService } from 'angular-oauth2-oidc';
import { ConfigService } from './config.service';
import { NotifierService } from './shared/services/notifier.service';
import { drawerRoutes, ROUTE_PARAM_REGEX } from './shared/constantLibary';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements OnInit, OnDestroy {
sidenavContentInformation?: { id: number; type: string };
drawerOpen: boolean = false;

export class AppComponent implements OnInit {
constructor(
public router: Router,
private oauthService: OAuthService,
private configService: ConfigService,
private notifierService: NotifierService,
) {
// Try to login via url state
oauthService.loadDiscoveryDocumentAndTryLogin().then(() => {
Expand All @@ -43,49 +37,5 @@ export class AppComponent implements OnInit, OnDestroy {
}),
)
.subscribe();
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map((event) => event as NavigationEnd),
)
.subscribe((event) => {
drawerRoutes.forEach((route) => {
if (event.url.startsWith(`/${route}/`)) {
const match = event.url.match(ROUTE_PARAM_REGEX);
if (match) {
const id = parseInt(match[1]);
this.sidenavContentInformation = { id: id, type: route };
this.openDrawer();
}
}
});
});

this.notifierService.closeDetailSubject.subscribe(() => {
this.closeDrawer();
});
}

ngOnDestroy() {
this.notifierService.closeDetailSubject.unsubscribe();
}

enableScrolling() {
document.body.setAttribute('style', 'overflow: visible;');
}

private disableScrolling() {
document.body.setAttribute('style', 'overflow: hidden;');
}

openDrawer() {
this.drawerOpen = true;
this.disableScrolling();
}

closeDrawer() {
this.drawerOpen = false;
this.sidenavContentInformation = undefined;
this.router.navigate(['/']);
}
}
11 changes: 8 additions & 3 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { KeyresultComponent } from './keyresult/keyresult.component';
import { KeyresultDetailComponent } from './keyresult-detail/keyresult-detail.component';
import { ObjectiveDetailComponent } from './objective-detail/objective-detail.component';
import { MatSidenavModule } from '@angular/material/sidenav';
import { DrawerContentComponent } from './drawer-content/drawer-content.component';
import { ConfidenceComponent } from './confidence/confidence.component';
import { MatSliderModule } from '@angular/material/slider';
import { ErrorInterceptor } from './shared/interceptors/error-interceptor.service';
Expand All @@ -58,7 +57,9 @@ import { ConfirmDialogComponent } from './shared/dialog/confirm-dialog/confirm-d
import { CheckInFormComponent } from './shared/dialog/checkin/check-in-form/check-in-form.component';
import { UnitLabelTransformationPipe } from './shared/pipes/unit-label-transformation/unit-label-transformation.pipe';
import { ParseUnitValuePipe } from './shared/pipes/parse-unit-value/parse-unit-value.pipe';
import { ScoringComponent } from './shared/scoring/scoring/scoring.component';
import { SidepanelComponent } from './shared/custom/sidepanel/sidepanel.component';
import { CdkConnectedOverlay, CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
import { ScoringComponent } from './shared/custom/scoring/scoring.component';
import { QuarterFilterComponent } from './quarter-filter/quarter-filter.component';

function initOauthFactory(configService: ConfigService, oauthService: OAuthService) {
Expand Down Expand Up @@ -102,7 +103,6 @@ export const MY_FORMATS = {
ScoringComponent,
KeyresultDetailComponent,
ObjectiveDetailComponent,
DrawerContentComponent,
ApplicationBannerComponent,
KeyResultDialogComponent,
ConfirmDialogComponent,
Expand All @@ -118,6 +118,7 @@ export const MY_FORMATS = {
ParseUnitValuePipe,
ObjectiveFormComponent,
QuarterFilterComponent,
SidepanelComponent,
],
imports: [
CommonModule,
Expand All @@ -137,6 +138,7 @@ export const MY_FORMATS = {
MatInputModule,
MatTooltipModule,
MatAutocompleteModule,
OverlayModule,
ToastrModule.forRoot(),
MatProgressSpinnerModule,
TranslateModule.forRoot({
Expand All @@ -157,6 +159,9 @@ export const MY_FORMATS = {
MatDividerModule,
MatSidenavModule,
MatCheckboxModule,
CdkOverlayOrigin,
CdkConnectedOverlay,
CdkOverlayOrigin,
],
providers: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@import "_variables";

#topBarHeight {
height: 48px;
height: $top-bar-height;
}

#okrTopbar {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/confidence/confidence.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="d-flex align-items-center" *ngIf="checkIn.confidence">
<div class="d-flex align-items-center bg-light-gray justify-content-center" *ngIf="checkIn.confidence">
<div
[ngClass]="edit ? 'keyResult-attribute-edit' : 'keyResult-attribute-show'"
[ngStyle]="{ 'background-color': backgroundColor }"
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/confidence/confidence.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ p {
mat-slider {
min-width: 370px;
}

.bg-light-gray {
background-color: #f5f5f5;
}
2 changes: 1 addition & 1 deletion frontend/src/app/confidence/confidence.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class ConfidenceComponent implements OnChanges {
@Input() backgroundColor!: string;

ngOnChanges(changes: SimpleChanges) {
if (changes['checkIn']?.currentValue === undefined || changes['checkIn']?.currentValue === null) {
if (!changes['checkIn']?.currentValue) {
this.checkIn = { confidence: 5 } as CheckInMin;
}
}
Expand Down
8 changes: 0 additions & 8 deletions frontend/src/app/drawer-content/drawer-content.component.html

This file was deleted.

7 changes: 0 additions & 7 deletions frontend/src/app/drawer-content/drawer-content.component.scss

This file was deleted.

39 changes: 0 additions & 39 deletions frontend/src/app/drawer-content/drawer-content.component.spec.ts

This file was deleted.

12 changes: 0 additions & 12 deletions frontend/src/app/drawer-content/drawer-content.component.ts

This file was deleted.

Loading
Loading