feat(aio): add about component and data
This commit is contained in:
parent
ad639d783f
commit
97deb01b1f
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="grid-fluid l-space-bottom-8">
|
||||||
|
<h3 class="title center">Building For the Future</h3>
|
||||||
|
<p>
|
||||||
|
Angular is built by a team of engineers who share a passion for
|
||||||
|
making web development feel effortless. We believe that writing
|
||||||
|
beautiful apps should be joyful and fun. We're building a
|
||||||
|
platform for the future.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-fluid l-space-bottom-6">
|
||||||
|
<h3 class="title center">Current Contributors</h3>
|
||||||
|
<aio-contributor-list></aio-contributor-list>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Contributor } from './contributors.model';
|
||||||
|
import { ContributorService } from './contributor.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: `aio-contributor-list`,
|
||||||
|
template: `
|
||||||
|
<section *ngFor="let group of groups" class="grid-fluid">
|
||||||
|
<h4 class="title">{{group}}</h4>
|
||||||
|
<aio-contributor *ngFor="let person of contributorGroups[group]" [person]="person"></aio-contributor>
|
||||||
|
</section>`
|
||||||
|
})
|
||||||
|
export class ContributorListComponent implements OnInit {
|
||||||
|
contributorGroups = new Map<string, Contributor[]>();
|
||||||
|
groups: string[];
|
||||||
|
|
||||||
|
constructor(private contributorService: ContributorService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.contributorService.contributors.subscribe(cgs => {
|
||||||
|
this.groups = ['Lead', 'Google', 'Community'];
|
||||||
|
this.contributorGroups = cgs;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
import { Contributor } from './contributors.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'aio-contributor',
|
||||||
|
template: `
|
||||||
|
<header>
|
||||||
|
<img src="{{pictureBase}}{{person.picture || noPicture}}" alt="name" width="240" height="208">
|
||||||
|
<h3>{{person.name}}</h3>
|
||||||
|
<button *ngIf="person.bio" aria-label="View Bio" (click)="showBio=!showBio">View Bio</button>
|
||||||
|
|
||||||
|
<!-- TODO: get the twitter/website icons and get rid of text -->
|
||||||
|
<a *ngIf="person.twitter" href="https://twitter.com/{{person.twitter}}">
|
||||||
|
<span class="icon-twitter">twitter</span>
|
||||||
|
</a>
|
||||||
|
<a *ngIf="person.website" href="{{person.website}}">
|
||||||
|
<span class="icon-publ">website</span>
|
||||||
|
</a>
|
||||||
|
<p>{{person.bio}}</p>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<!-- TODO: This should be modal and float over the width of page -->
|
||||||
|
<article *ngIf="showBio">
|
||||||
|
<h3>{{person.name}}</h3>
|
||||||
|
<p>{{person.bio}}</p>
|
||||||
|
<article>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class ContributorComponent {
|
||||||
|
@Input() person: Contributor;
|
||||||
|
showBio = false;
|
||||||
|
noPicture = '_no-one.png';
|
||||||
|
pictureBase = 'content/images/bios/';
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Http } from '@angular/http';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
import 'rxjs/add/operator/publishLast';
|
||||||
|
|
||||||
|
import { Logger } from 'app/shared/logger.service';
|
||||||
|
import { Contributor } from './contributors.model';
|
||||||
|
|
||||||
|
const contributorsPath = 'content/contributors.json';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ContributorService {
|
||||||
|
contributors: Observable<Map<string, Contributor[]>>;
|
||||||
|
|
||||||
|
constructor(private http: Http, private logger: Logger) {
|
||||||
|
this.contributors = this.getContributors();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getContributors() {
|
||||||
|
const contributors = this.http.get(contributorsPath)
|
||||||
|
.map(res => res.json())
|
||||||
|
.map(contribs => {
|
||||||
|
const contribGroups = new Map<string, Contributor[]>();
|
||||||
|
|
||||||
|
Object.keys(contribs).forEach(key => {
|
||||||
|
const contributor = contribs[key];
|
||||||
|
const group = contributor.group;
|
||||||
|
const contribGroup = contribGroups[group];
|
||||||
|
if (contribGroup) {
|
||||||
|
contribGroup.push(contributor);
|
||||||
|
} else {
|
||||||
|
contribGroups[group] = [contributor];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return contribGroups;
|
||||||
|
})
|
||||||
|
.publishLast();
|
||||||
|
contributors.connect();
|
||||||
|
return contributors;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
export class Contributor {
|
||||||
|
group: string;
|
||||||
|
name: string;
|
||||||
|
picture?: string;
|
||||||
|
website?: string;
|
||||||
|
twitter?: string;
|
||||||
|
bio?: string;
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import { PrettyPrinter } from './code/pretty-printer.service';
|
import { ContributorService } from './contributor/contributor.service';
|
||||||
import { CopierService } from 'app/shared/copier.service';
|
import { CopierService } from 'app/shared/copier.service';
|
||||||
|
import { PrettyPrinter } from './code/pretty-printer.service';
|
||||||
|
|
||||||
// Any components that we want to use inside embedded components must be declared or imported here
|
// Any components that we want to use inside embedded components must be declared or imported here
|
||||||
// It is not enough just to import them inside the AppModule
|
// It is not enough just to import them inside the AppModule
|
||||||
|
@ -16,6 +16,8 @@ import { CodeComponent } from './code/code.component';
|
||||||
import { ApiListComponent } from './api/api-list.component';
|
import { ApiListComponent } from './api/api-list.component';
|
||||||
import { CodeExampleComponent } from './code/code-example.component';
|
import { CodeExampleComponent } from './code/code-example.component';
|
||||||
import { CodeTabsComponent } from './code/code-tabs.component';
|
import { CodeTabsComponent } from './code/code-tabs.component';
|
||||||
|
import { ContributorListComponent } from './contributor/contributor-list.component';
|
||||||
|
import { ContributorComponent } from './contributor/contributor.component';
|
||||||
import { DocTitleComponent } from './doc-title.component';
|
import { DocTitleComponent } from './doc-title.component';
|
||||||
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component';
|
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component';
|
||||||
|
|
||||||
|
@ -23,7 +25,8 @@ import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/l
|
||||||
* such as CodeExampleComponent, LiveExampleComponent,...
|
* such as CodeExampleComponent, LiveExampleComponent,...
|
||||||
*/
|
*/
|
||||||
export const embeddedComponents: any[] = [
|
export const embeddedComponents: any[] = [
|
||||||
ApiListComponent, CodeExampleComponent, DocTitleComponent, CodeTabsComponent, LiveExampleComponent
|
ApiListComponent, CodeExampleComponent, CodeTabsComponent,
|
||||||
|
ContributorListComponent, DocTitleComponent, LiveExampleComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Injectable class w/ property returning components that can be embedded in docs */
|
/** Injectable class w/ property returning components that can be embedded in docs */
|
||||||
|
@ -36,12 +39,14 @@ export class EmbeddedComponents {
|
||||||
declarations: [
|
declarations: [
|
||||||
embeddedComponents,
|
embeddedComponents,
|
||||||
CodeComponent,
|
CodeComponent,
|
||||||
|
ContributorComponent,
|
||||||
EmbeddedPlunkerComponent
|
EmbeddedPlunkerComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
ContributorService,
|
||||||
|
CopierService,
|
||||||
EmbeddedComponents,
|
EmbeddedComponents,
|
||||||
PrettyPrinter,
|
PrettyPrinter
|
||||||
CopierService
|
|
||||||
],
|
],
|
||||||
entryComponents: [ embeddedComponents ]
|
entryComponents: [ embeddedComponents ]
|
||||||
})
|
})
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,128 @@
|
||||||
|
$unit: 8px;
|
||||||
|
$metal: #536E7A;
|
||||||
|
$snow: #FFFFFF;
|
||||||
|
$steel: #253238;
|
||||||
|
|
||||||
|
aio-contributor-list {
|
||||||
|
.grid-fluid {
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 6 * 8px;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.grid-fluid aio-contributor {
|
||||||
|
display: inline;
|
||||||
|
float: left;
|
||||||
|
margin-right: 1.04167%;
|
||||||
|
margin-left: 1.04167%;
|
||||||
|
width: 22.91667%;
|
||||||
|
margin-bottom: 6 * 8px;
|
||||||
|
}
|
||||||
|
.grid-fluid:after, .grid-fluid:before {
|
||||||
|
content: '.';
|
||||||
|
clear: both;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
font-size: 0;
|
||||||
|
line-height: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||||
|
/* line 6, ../scss/_responsive.scss */
|
||||||
|
.grid-fluid{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||||
|
.grid-fluid{
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
aio-contributor {
|
||||||
|
margin: 0px 0px ($unit * 4) 0px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.26);
|
||||||
|
background: $snow;
|
||||||
|
transition: all .3s;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translate3d(0,-3px,0);
|
||||||
|
box-shadow: 0px 8px 16px 0 rgba(0, 0, 0, 0.4);
|
||||||
|
|
||||||
|
nav {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// HEADER
|
||||||
|
|
||||||
|
header {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 2px 2px 0px 0px;
|
||||||
|
|
||||||
|
nav {
|
||||||
|
transition: opacity .5s;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
padding: $unit;
|
||||||
|
background: rgba($steel, .4);
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $snow;
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: .87;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $snow;
|
||||||
|
font-size: 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
opacity: .87;
|
||||||
|
margin-right: $unit;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MAIN CONTENT
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: $metal;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: $unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
@import 'hamburger';
|
@import 'hamburger';
|
||||||
@import 'code';
|
@import 'code';
|
||||||
|
@import 'contributor';
|
||||||
@import 'alert';
|
@import 'alert';
|
||||||
@import 'filetree';
|
@import 'filetree';
|
||||||
@import 'images';
|
@import 'images';
|
||||||
|
|
|
@ -151,7 +151,7 @@ module.exports =
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
basePath: CONTENTS_PATH,
|
basePath: CONTENTS_PATH,
|
||||||
include: CONTENTS_PATH + '/marketing/contributor.json',
|
include: CONTENTS_PATH + '/marketing/contributors.json',
|
||||||
fileReader: 'jsonFileReader'
|
fileReader: 'jsonFileReader'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -286,7 +286,7 @@ module.exports =
|
||||||
outputPathTemplate: '${path}.json'
|
outputPathTemplate: '${path}.json'
|
||||||
},
|
},
|
||||||
{docTypes: ['navigation-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
|
{docTypes: ['navigation-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
|
||||||
{docTypes: ['contributor-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}
|
{docTypes: ['contributors-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue