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

Extensions: Use annotations for extensions #2962

Merged
merged 37 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
19fc919
Extensions: Use annotations for extensions. Add first set of extensio…
nwmac Sep 7, 2018
a2623d9
Fix some lint issues
nwmac Sep 7, 2018
1d54aaa
Merge branch 'v2-master' into ext-tabs-and-actions
nwmac Sep 7, 2018
3916c06
Fix max-line-length lint issue
nwmac Sep 9, 2018
db2d776
Fix a couple of code climate issues
nwmac Sep 9, 2018
84588b8
Fix unit tests. Correct example folder name
nwmac Sep 10, 2018
73f99f1
Tweaks to example theme
nwmac Sep 10, 2018
a8f87a7
Fix code climate issues
nwmac Sep 10, 2018
1d6d93a
Merge remote-tracking branch 'origin/v2-master' into ext-tabs-and-act…
nwmac Sep 11, 2018
6b147e7
Update package lock
nwmac Sep 11, 2018
c7506ea
Merge remote-tracking branch 'origin/v2-master' into ext-tabs-and-act…
nwmac Sep 11, 2018
baff023
Wire in remaining actions
nwmac Sep 11, 2018
120a8b4
Merge remote-tracking branch 'origin/v2-master' into ext-tabs-and-act…
nwmac Sep 21, 2018
d0fd16b
Remove example (will put in separate PR)
nwmac Sep 21, 2018
2dd5ae1
Merge remote-tracking branch 'origin/ext-tabs-and-actions' into ext-e…
nwmac Sep 21, 2018
9827d80
Add example
nwmac Sep 21, 2018
61ac011
Remove comma
nwmac Sep 21, 2018
f3f1887
Tidy ups
nwmac Sep 21, 2018
c1c451d
Merge branch 'ext-tabs-and-actions' of github.com:cloudfoundry-incuba…
nwmac Sep 21, 2018
2404465
Fix Extension init
nwmac Sep 21, 2018
c6a566e
Remove old depenency
nwmac Sep 27, 2018
82d3098
Merge remote-tracking branch 'origin/v2-master' into ext-tabs-and-act…
nwmac Oct 11, 2018
3a0325a
Remove whitespace to fix lint issue
nwmac Oct 11, 2018
96ee0a2
Remove white space
nwmac Oct 13, 2018
ef35f84
Fix merge issue
nwmac Oct 13, 2018
17b70fc
Fix for cancel not working for user management dialog
nwmac Oct 15, 2018
1c4ad30
Better fix for user mgmt stepper not being able to cancel
nwmac Oct 15, 2018
bad4dc4
Fix user mgmt nav issue
nwmac Oct 15, 2018
086626f
Move extension buttons component into the page header
Oct 16, 2018
d1f5de5
Tidy up and fixes
Oct 16, 2018
b60ce38
Merge branch 'ext-example' into ext-tabs-and-actions
Oct 16, 2018
b0e990c
Merge remote-tracking branch 'origin/ext-tabs-and-actions' into ext-e…
nwmac Oct 16, 2018
f6604ec
Compile fix and theme tweak
nwmac Oct 16, 2018
2d9c688
Merge branch 'ext-example' into ext-tabs-and-actions
Oct 16, 2018
9af9be2
Fix compilation error due to logoText not being added to Cuistomizato…
nwmac Oct 16, 2018
f9bff0a
Ensure extention buttons appear on the right, not next to the title
nwmac Oct 16, 2018
15023ef
Fix example
nwmac Oct 16, 2018
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
2 changes: 1 addition & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"preserveSymlinks": true,
"sourceMap": false,
"main": "src/frontend/test.ts",
"karmaConfig": "./karma.conf.js",
"sourceMap": false,
"polyfills": "src/frontend/polyfills.ts",
"tsConfig": "src/frontend/tsconfig.spec.json",
"scripts": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<app-intro-screen class="acme-login login__busy" [ngClass]="{'acme-login__busy': busy$ | async }">
<mat-card class="login__card mat-elevation-z">
<app-stratos-title></app-stratos-title>
<div class="acme-login__body">
<div class="acme-login__form-outer" [ngClass]="{'acme-login-sso': ssoLogin}">
<form class="acme-login__form" name="loginForm" (ngSubmit)="login()" #loginForm="ngForm">
<mat-form-field *ngIf="!ssoLogin">
<input matInput required [(ngModel)]="username" name="username" placeholder="Username">
</mat-form-field>
<mat-form-field *ngIf="!ssoLogin">
<input matInput required type="password" [(ngModel)]="password" name="password" placeholder="Password">
</mat-form-field>
<button class="login__submit" color="primary" *ngIf="!loggedIn" type="submit" mat-button mat-raised-button [disabled]="!ssoLogin && !loginForm.valid">Login</button>
</form>
</div>
<div class="acme-login__loading">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>
</div>
</mat-card>
<div class="acme-login-message" [ngClass]="{'login-message--show': !!message, 'login-message-error': this.error}">
{{ message }}
</div>
<div class="acme-login__footer">
<div class="acme-login__copyright">
<span *ngIf="config.copyright" [innerHTML]="config.copyright"></span>
</div>
<div class="acme-login__logo">
<img src="/assets/custom/acme_logo.png">
</div>
</div>
</app-intro-screen>

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
@import '../../../sass/custom/acme-colors';
.acme-login {
&__card.mat-card {
box-shadow: 0 0 20px 9px rgba(0, 0, 0, .2);
padding: 0;
width: 320px;
mat-form-field {
width: 100%;
}
}
&__body {
padding: 24px;
padding-top: 0;
}
&__submit {
width: 100%;
}
&-message {
font-size: 18px;
height: 20px;
padding-top: 20px;
}
&__form {
display: flex;
flex-direction: column;
}
&__form-outer {
$cubic: cubic-bezier(.215, .61, .355, 1);
$time: 250ms;
height: 180px;
opacity: 1;
transition: height $time $cubic 100ms, opacity $time * 2 $cubic $time + 50ms;
&.login-sso {
height: auto;
}
}
&__loading {
display: none;
}
&__busy {
.login__form {
display: none;
}
.login__form-outer {
height: 0;
opacity: 0;
}
.login__loading {
display: block;
}
}
&__footer {
align-items: center;
bottom: 0;
display: flex;
flex: 0 0 auto;
flex-direction: row;
padding: 20px 0;
position: absolute;
width: 90%;
}
&__copyright {
color: #333;
flex: 1;
}
&__logo {
img {
width: 79px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { CommonModule } from '@angular/common';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule } from '@ngrx/store';

import { CoreModule } from '../../core/core.module';
import { SharedModule } from '../../shared/shared.module';
import { appReducers } from '../../store/reducers.module';
import { AcmeLoginComponent } from './acme-login.component';

describe('AcmeLoginComponent', () => {
let component: AcmeLoginComponent;
let fixture: ComponentFixture<AcmeLoginComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AcmeLoginComponent ],
imports: [
CommonModule,
CoreModule,
SharedModule,
RouterTestingModule,
BrowserAnimationsModule,
StoreModule.forRoot(appReducers)
]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AcmeLoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Customizations, CustomizationsMetadata } from '../../core/customizations.types';
import { LoginPageComponent } from '../../features/login/login-page/login-page.component';
import { AppState } from '../../store/app-state';
import { StratosLoginComponent } from '../../core/extension/extension-service';

@StratosLoginComponent()
@Component({
selector: 'app-acme-login',
templateUrl: './acme-login.component.html',
styleUrls: ['./acme-login.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class AcmeLoginComponent extends LoginPageComponent {

constructor(
store: Store<AppState>,
router: Router,
@Inject(Customizations) public config: CustomizationsMetadata
) {
super(store, router);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<app-page-header>
Example custom component
</app-page-header>

Example custom component invoked by a custom action
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AppActionExtensionComponent } from './app-action-extension.component';
import { CoreModule } from '../../core/core.module';
import { RouterTestingModule } from '@angular/router/testing';
import { SharedModule } from '../../shared/shared.module';
import { createBasicStoreModule } from '../../test-framework/store-test-helper';

describe('AppActionExtensionComponent', () => {
let component: AppActionExtensionComponent;
let fixture: ComponentFixture<AppActionExtensionComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AppActionExtensionComponent ],
imports: [
CoreModule,
RouterTestingModule,
SharedModule,
createBasicStoreModule()
]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AppActionExtensionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component, OnInit } from '@angular/core';
import { StratosTab, StratosTabType, StratosAction, StratosActionType } from '../../core/extension/extension-service';

@StratosAction({
type: StratosActionType.Applications,
label: 'Custom App Action',
link: 'exampleAction',
icon: 'extension'
})
@Component({
selector: 'app-app-action-extension',
templateUrl: './app-action-extension.component.html',
styleUrls: ['./app-action-extension.component.scss']
})
export class AppActionExtensionComponent implements OnInit {

constructor() { }

ngOnInit() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Example custom tab
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AppTabExtensionComponent } from './app-tab-extension.component';
import { CoreModule } from '../../core/core.module';
import { RouterTestingModule } from '@angular/router/testing';
import { SharedModule } from '../../shared/shared.module';
import { createBasicStoreModule } from '../../test-framework/store-test-helper';

describe('AppTabExtensionComponent', () => {
let component: AppTabExtensionComponent;
let fixture: ComponentFixture<AppTabExtensionComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AppTabExtensionComponent ],
imports: [
CoreModule,
RouterTestingModule,
SharedModule,
createBasicStoreModule()
]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AppTabExtensionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component, OnInit } from '@angular/core';
import { StratosTab, StratosTabType, StratosAction, StratosActionType } from '../../core/extension/extension-service';

@StratosTab({
type: StratosTabType.Application,
label: 'Example App Tab',
link: 'example'
})
@Component({
selector: 'app-app-tab-extension',
templateUrl: './app-tab-extension.component.html',
styleUrls: ['./app-tab-extension.component.scss']
})
export class AppTabExtensionComponent implements OnInit {

constructor() { }

ngOnInit() {
}

}
50 changes: 50 additions & 0 deletions examples/custom-src/frontend/app/custom/custom.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { NgModule } from '@angular/core';
import { CoreModule } from '../core/core.module';
import { Customizations, CustomizationsMetadata } from '../core/customizations.types';
import { MDAppModule } from '../core/md.module';
import { SharedModule } from '../shared/shared.module';
import { AcmeLoginComponent } from './acme-login/acme-login.component';
import { StratosExtension } from '../core/extension/extension-service';
import { AppTabExtensionComponent } from './app-tab-extension/app-tab-extension.component';
import { AppActionExtensionComponent } from './app-action-extension/app-action-extension.component';

const AcmeCustomizations: CustomizationsMetadata = {
copyright: '&copy; 2018 ACME Corp',
hasEula: true,
};

// CustomModule is bundled in to the main application bundle
@StratosExtension({
routes: [{
path: 'example',
loadChildren: 'app/custom/nav-extension/nav-extension.module#NavExtensionModule',
data: {
stratosNavigation: {
text: 'Example',
matIcon: 'extension'
}
}
}]
})
@NgModule({
imports: [
CoreModule,
SharedModule,
MDAppModule,
],
declarations: [
AcmeLoginComponent,
AppTabExtensionComponent,
AppActionExtensionComponent
],
entryComponents: [
AcmeLoginComponent,
// You must specify the tab and action as an entry components
AppTabExtensionComponent,
AppActionExtensionComponent
],
providers: [
{ provide: Customizations, useValue: AcmeCustomizations }
],
})
export class CustomModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<app-page-header>
<h1>Example Stratos Navigation Extension</h1>
</app-page-header>
<h1>Example Stratos Navigation Extension</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Component } from '@angular/core';

@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
})
export class ExampleComponent {}

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { NavExtensionRoutingModule } from './nav-extension.routing';
import { ExampleComponent } from './example-component/example.component';
import { CoreModule } from '../../core/core.module';
import { SharedModule } from '../../shared/shared.module';

@NgModule({
imports: [
CoreModule,
SharedModule,
NavExtensionRoutingModule,
],
declarations: [
ExampleComponent
],
entryComponents: [
ExampleComponent
]
})
export class NavExtensionModule {}
Loading