Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 5f72cd4

Browse files
oodamienghillert
authored andcommitted
Layout Module
Resolves #721
1 parent ff417d7 commit 5f72cd4

14 files changed

+434
-126
lines changed

ui/src/app/app.component.html

Lines changed: 9 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,9 @@
1-
<nav class="navbar navbar-inverse navbar-static-top">
2-
<div class="container">
3-
<div class="navbar-header">
4-
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
5-
[attr.aria-expanded]="!isCollapsed" (click)="toggleCollapse()" [ngClass]="{'collapsed': isCollapsed}">
6-
<span class="sr-only">Toggle navigation</span>
7-
<span class="icon-bar"></span>
8-
<span class="icon-bar"></span>
9-
<span class="icon-bar"></span>
10-
</button>
11-
<a class="navbar-brand" routerLink="apps"><span></span></a>
12-
</div>
13-
<div id="navbar" class="collapse navbar-collapse" [ngClass]="{'in': !isCollapsed}">
14-
<ul class="nav navbar-nav navbar-right" (click)="collapse()">
15-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']"><a routerLink="apps">Apps</a></li>
16-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']" appFeature="streamsEnabled"><a routerLink="runtime/apps">Runtime</a></li>
17-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']" appFeature="streamsEnabled"><a routerLink="streams">Streams</a></li>
18-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']" appFeature="tasksEnabled"><a routerLink="tasks">Tasks</a></li>
19-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']" appFeature="tasksEnabled"><a routerLink="jobs">Jobs</a></li>
20-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']" appFeature="analyticsEnabled"><a routerLink="analytics">Analytics</a></li>
21-
<li routerLinkActive="active" [appRoles]="['ROLE_VIEW']"><a routerLink="about">About</a></li>
22-
<li *ngIf="securityInfo.isAuthenticationEnabled"
23-
dropdown
24-
class="dropdown"><a class="dropdown-toggle" dropdownToggle (click)="false"><span class="glyphicon glyphicon-user"></span><b class="caret"></b></a>
25-
<ul *dropdownMenu class="dropdown-menu">
26-
<li *ngIf="securityInfo.isAuthenticated">{{ securityInfo.username }}</li>
27-
<li *ngIf="!securityInfo.isAuthenticated">Not logged in.</li>
28-
<li *ngIf="securityInfo.isAuthenticated"><a routerLink="logout">Logout</a></li>
29-
<li *ngIf="!securityInfo.isAuthenticated"><a routerLink="login">Login</a></li>
30-
</ul>
31-
</li>
32-
</ul>
33-
</div>
34-
</div>
35-
</nav>
36-
<div class="container dataflow-main-container">
37-
<div class='row'>
38-
<div class='col-sm-24'><ng2-toasty></ng2-toasty>
39-
<ng-template [ngBusy]="{busy: busy, minDuration: 500}"></ng-template>
40-
<router-outlet></router-outlet>
41-
</div>
42-
</div>
43-
</div>
44-
<div class='pane footer' id="footer">
45-
<div class='container'>
46-
<div class='row'>
47-
<div class='col-sm-12'>
48-
<p id="copyright-notice">
49-
© 2017&ndash;2018 <a target="_blank" href="https://pivotal.io/">Pivotal Software</a>, Inc.
50-
<br>
51-
All Rights Reserved.
52-
</p>
53-
</div>
54-
<div class='col-sm-4'>
55-
<h3 class='h4'>Project</h3>
56-
<ul class='list-unstyled'>
57-
<li>
58-
<a class='link-lowlight-alt' target="_blank" href='https://cloud.spring.io/spring-cloud-dataflow/'>Project Page</a>
59-
</li>
60-
<li>
61-
<a class='link-lowlight-alt' target="_blank" href='https://github.com/spring-cloud/spring-cloud-dataflow/issues'>Issue Tracker</a>
62-
</li>
63-
</ul>
64-
</div>
65-
<div class='col-sm-4'>
66-
<h3 class='h4'>Documentation</h3>
67-
<ul class='list-unstyled'>
68-
<li *ngIf="dataflowVersionInfo$ | async as aboutInfo">
69-
<a class='link-lowlight-alt' target="_blank" href='https://docs.spring.io/spring-cloud-dataflow/docs/{{ aboutInfo.versionInfo.core.version }}/reference/htmlsingle/'>Docs</a>
70-
</li>
71-
<li>
72-
<a class='link-lowlight-alt' target="_blank" href='https://github.com/spring-cloud/spring-cloud-dataflow'>Sources</a>
73-
</li>
74-
<li *ngIf="dataflowVersionInfo$ | async as aboutInfo">
75-
<a class='link-lowlight-alt' target="_blank" href='https://docs.spring.io/spring-cloud-dataflow/docs/{{ aboutInfo.versionInfo.core.version }}/api/'>Api Docs</a>
76-
</li>
77-
</ul>
78-
</div>
79-
<div class='col-sm-5 col-md-4'>
80-
<h3 class='h4'>Need Help?</h3>
81-
<ul class='list-unstyled'>
82-
<li>
83-
For questions + support:
84-
<a class='link-lowlight-alt' target="_blank" href='https://stackoverflow.com/questions/tagged/spring-cloud-dataflow'>Stackoverflow</a>
85-
</li>
86-
</ul>
87-
</div>
88-
</div>
89-
</div>
90-
</div>
1+
<app-navigation></app-navigation>
2+
3+
<app-body>
4+
<ng2-toasty></ng2-toasty>
5+
<ng-template [ngBusy]="{busy: busy, minDuration: 500}"></ng-template>
6+
<router-outlet></router-outlet>
7+
</app-body>
8+
9+
<app-footer></app-footer>

ui/src/app/app.component.ts

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,28 @@
1-
import { Component, DoCheck } from '@angular/core';
1+
import { Component } from '@angular/core';
22
import { ToastyConfig } from 'ng2-toasty';
3-
import { AuthService } from './auth/auth.service';
43
import { Renderer2 } from '@angular/core';
54
import { OnInit } from '@angular/core';
6-
7-
import { SecurityInfo } from './shared/model/about/security-info.model';
8-
import { SharedAboutService } from './shared/services/shared-about.service';
9-
import { Observable } from 'rxjs/Observable';
10-
import { AboutInfo } from './shared/model/about/about-info.model';
115
import { BusyService } from './shared/services/busy.service';
126

137
@Component({
148
selector: 'app-root',
159
templateUrl: './app.component.html',
1610
})
17-
export class AppComponent implements DoCheck, OnInit {
18-
19-
public securityInfo: SecurityInfo;
20-
public dataflowVersionInfo$: Observable<AboutInfo>;
11+
export class AppComponent implements OnInit {
2112

22-
public isCollapsed = true;
2313
public busy: any = [];
2414

2515
constructor(private toastyConfig: ToastyConfig,
26-
private renderer: Renderer2,
27-
private authService: AuthService,
28-
private busyService: BusyService,
29-
private sharedAboutService: SharedAboutService) {
16+
private renderer: Renderer2,
17+
private busyService: BusyService) {
3018
this.toastyConfig.theme = 'bootstrap';
3119
this.toastyConfig.limit = 5;
3220
this.toastyConfig.showClose = true;
33-
this.toastyConfig.position = 'top-right';
34-
this.toastyConfig.timeout = 3000;
35-
36-
this.securityInfo = authService.securityInfo;
37-
}
38-
39-
ngDoCheck() {
40-
this.securityInfo = this.authService.securityInfo;
21+
this.toastyConfig.position = 'top-right';
22+
this.toastyConfig.timeout = 3000;
4123
}
4224

4325
ngOnInit() {
44-
this.dataflowVersionInfo$ = this.sharedAboutService.getAboutInfo();
4526
this.renderer.listen('document', 'scroll', (evt) => {
4627
this.updateToasty();
4728
});
@@ -76,11 +57,9 @@ export class AppComponent implements DoCheck, OnInit {
7657
const navHeight = document.getElementsByTagName('nav')[0].offsetHeight;
7758
let marginToParent = 10;
7859
const toastyElement = document.getElementById('toasty');
79-
8060
if (window.outerWidth <= 768) {
8161
marginToParent = 0;
8262
}
83-
8463
if (bodyScrollTop > navHeight) {
8564
toastyElement.style.top = marginToParent + 'px';
8665
} else if (bodyScrollTop >= 0) {
@@ -89,13 +68,4 @@ export class AppComponent implements DoCheck, OnInit {
8968
}
9069
}
9170

92-
public toggleCollapse(): void {
93-
this.isCollapsed = !this.isCollapsed;
94-
}
95-
96-
public collapse(): void {
97-
if (!this.isCollapsed) {
98-
this.isCollapsed = true;
99-
}
100-
}
10171
}

ui/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { BrowserAnimationsModule} from '@angular/platform-browser/animations';
2121
import { AuthService } from './auth/auth.service';
2222
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
2323
import { SharedAboutService } from './shared/services/shared-about.service';
24+
import { LayoutModule } from './layout/layout.module';
2425

2526
/**
2627
* Executed when the app starts up. Will load the security
@@ -57,6 +58,7 @@ export function init(authService: AuthService, sharedAboutService: SharedAboutSe
5758
SharedModule,
5859
StreamsModule,
5960
TasksModule,
61+
LayoutModule,
6062
BsDropdownModule.forRoot()
6163
],
6264
providers: [
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div class="container dataflow-main-container">
2+
<div class='row'>
3+
<div class='col-sm-24'>
4+
<ng-content></ng-content>
5+
</div>
6+
</div>
7+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { NgxPaginationModule } from 'ngx-pagination';
3+
import { ModalModule } from 'ngx-bootstrap';
4+
import { NgBusyModule } from 'ng-busy';
5+
import { BodyComponent } from './body.component';
6+
7+
describe('BodyComponent', () => {
8+
let component: BodyComponent;
9+
let fixture: ComponentFixture<BodyComponent>;
10+
11+
beforeEach(async(() => {
12+
TestBed.configureTestingModule({
13+
declarations: [
14+
BodyComponent
15+
],
16+
imports: [
17+
NgBusyModule,
18+
NgxPaginationModule,
19+
ModalModule.forRoot()
20+
],
21+
providers: []
22+
})
23+
.compileComponents();
24+
}));
25+
26+
beforeEach(() => {
27+
fixture = TestBed.createComponent(BodyComponent);
28+
component = fixture.componentInstance;
29+
});
30+
31+
it('should be created', () => {
32+
fixture.detectChanges();
33+
expect(component).toBeTruthy();
34+
});
35+
36+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { Observable } from 'rxjs/Observable';
3+
import { AboutInfo } from '../../shared/model/about/about-info.model';
4+
import { SharedAboutService } from '../../shared/services/shared-about.service';
5+
6+
/**
7+
* Body component
8+
*
9+
* @author Gunnar Hillert
10+
* @author Damien Vitrac
11+
*/
12+
@Component({
13+
selector: 'app-body',
14+
templateUrl: './body.component.html',
15+
})
16+
export class BodyComponent implements OnInit {
17+
18+
/**
19+
* Constructor
20+
*/
21+
constructor() {
22+
}
23+
24+
/**
25+
* Initialize
26+
*/
27+
ngOnInit(): void {
28+
}
29+
30+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<div class="footer" id="footer">
2+
<div class='container'>
3+
<div class='row'>
4+
<div class='col-sm-12'>
5+
<p id="copyright-notice">
6+
© 2017&ndash;2018 <a target="_blank" href="https://pivotal.io/">Pivotal Software</a>, Inc.
7+
<br>
8+
All Rights Reserved.
9+
</p>
10+
</div>
11+
<div class='col-sm-4'>
12+
<h3 class='h4'>Project</h3>
13+
<ul class='list-unstyled'>
14+
<li>
15+
<a class='link-lowlight-alt' target="_blank" href='https://cloud.spring.io/spring-cloud-dataflow/'>Project
16+
Page</a>
17+
</li>
18+
<li>
19+
<a class='link-lowlight-alt' target="_blank"
20+
href='https://github.com/spring-cloud/spring-cloud-dataflow/issues'>Issue Tracker</a>
21+
</li>
22+
</ul>
23+
</div>
24+
<div class='col-sm-4'>
25+
<h3 class='h4'>Documentation</h3>
26+
<ul class='list-unstyled'>
27+
<li *ngIf="dataflowVersionInfo$ | async as aboutInfo">
28+
<a class='link-lowlight-alt' target="_blank"
29+
href='https://docs.spring.io/spring-cloud-dataflow/docs/{{ aboutInfo.versionInfo.core.version }}/reference/htmlsingle/'>Docs</a>
30+
</li>
31+
<li>
32+
<a class='link-lowlight-alt' target="_blank" href='https://github.com/spring-cloud/spring-cloud-dataflow'>Sources</a>
33+
</li>
34+
<li *ngIf="dataflowVersionInfo$ | async as aboutInfo">
35+
<a class='link-lowlight-alt' target="_blank"
36+
href='https://docs.spring.io/spring-cloud-dataflow/docs/{{ aboutInfo.versionInfo.core.version }}/api/'>Api
37+
Docs</a>
38+
</li>
39+
</ul>
40+
</div>
41+
<div class='col-sm-5 col-md-4'>
42+
<h3 class='h4'>Need Help?</h3>
43+
<ul class='list-unstyled'>
44+
<li>
45+
For questions + support:
46+
<a class='link-lowlight-alt' target="_blank"
47+
href='https://stackoverflow.com/questions/tagged/spring-cloud-dataflow'>Stackoverflow</a>
48+
</li>
49+
</ul>
50+
</div>
51+
</div>
52+
</div>
53+
</div>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { BsDropdownModule } from 'ngx-bootstrap';
3+
import { FooterComponent } from './footer.component';
4+
import { MocksSharedAboutService } from '../../tests/mocks/shared-about';
5+
import { SharedAboutService } from '../../shared/services/shared-about.service';
6+
import { MockAuthService } from '../../tests/mocks/auth';
7+
import { AuthService } from '../../auth/auth.service';
8+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
9+
import { SharedModule } from '../../shared/shared.module';
10+
import { CommonModule } from '@angular/common';
11+
import { BrowserModule } from '@angular/platform-browser';
12+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
13+
import { RouterModule } from '@angular/router';
14+
15+
xdescribe('FooterComponent', () => {
16+
let component: FooterComponent;
17+
let fixture: ComponentFixture<FooterComponent>;
18+
const authService = new MockAuthService();
19+
const aboutService = new MocksSharedAboutService();
20+
21+
beforeEach(async(() => {
22+
TestBed.configureTestingModule({
23+
declarations: [
24+
FooterComponent
25+
],
26+
imports: [
27+
CommonModule,
28+
FormsModule,
29+
ReactiveFormsModule,
30+
BrowserModule,
31+
RouterModule,
32+
BrowserAnimationsModule,
33+
SharedModule,
34+
BsDropdownModule.forRoot(),
35+
],
36+
providers: [
37+
{ provide: SharedAboutService, useValue: aboutService },
38+
{ provide: AuthService, useValue: authService }
39+
]
40+
}).compileComponents();
41+
}));
42+
43+
beforeEach(() => {
44+
fixture = TestBed.createComponent(FooterComponent);
45+
component = fixture.componentInstance;
46+
});
47+
48+
it('should be created', () => {
49+
fixture.detectChanges();
50+
expect(component).toBeTruthy();
51+
});
52+
53+
});

0 commit comments

Comments
 (0)