feat(docs-infra): created new widget for events page (#36517)

Data in events page was hardcoded and it is manually moved in the table.

Created a new events widget which will automatically move past and upcoming
events from events.json (`aio/content/marketing/events.json`) file to the
relevant table in the events tab

PR Close #36517
This commit is contained in:
ajitsinghkaler 2020-06-11 13:49:10 +03:00 committed by Andrew Kushnir
parent 44074499dc
commit 5b33798796
12 changed files with 792 additions and 167 deletions

View File

@ -3,162 +3,5 @@
</header> </header>
<article class="events-container"> <article class="events-container">
<p>Where we'll be presenting:</p> <aio-events></aio-events>
<table class="is-full-width">
<thead>
<tr>
<th>Event</th>
<th>Location</th>
<th>Date</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p>Where we already presented:</p>
<table class="is-full-width">
<thead>
<tr>
<th>Event</th>
<th>Location</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<!-- ng-vikings 2020 -->
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Oslo, Norway</td>
<td>May 25-26 conference, 27 workshops, 2020</td>
</tr>
<!-- ng-conf 2020 -->
<tr>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 1-3, 2020</td>
</tr>
<!-- ngIndia 2020 -->
<tr>
<th><a href="https://www.ng-ind.com/" title="ngIndia">ngIndia</a></th>
<td>Delhi, India</td>
<td>Feb 29, 2020</td>
</tr>
<!-- ReactiveConf 2019 -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 30 - November 1, 2019</td>
</tr>
<!-- NG Rome 2019-->
<tr>
<th>
<a href="https://ngrome.io" title="NG Rome MMXIX - The Italian Angular Conference">NG Rome MMXIX</a>
</th>
<td>Rome, Italy</td>
<td>Oct 6th workshops, 7th conference, 2019</td>
</tr>
<!-- AngularConnect 2019-->
<tr>
<th><a href="https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral"
title="AngularConnect">AngularConnect</a></th>
<td>London, UK</td>
<td>September 19-20, 2019</td>
</tr>
<!-- NG-DE 2019-->
<tr>
<th><a href="https://ng-de.org/" title="NG-DE">NG-DE</a></th>
<td>Berlin, Germany</td>
<td>August 29th workshops, 30-31 conference, 2019</td>
</tr>
<!-- ngJapan-->
<tr>
<th><a href="https://ngjapan.org" title="ng-japan">ng-japan</a></th>
<td>Tokyo, Japan</td>
<td>July 13, 2019</td>
</tr>
<!-- ngVikings 2019-->
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Copenhagen, Denmark</td>
<td>May 26 (workshops), 27-28 (conference), 2019</td>
</tr>
<!-- ng-conf 2019-->
<tr>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>May 1-3, 2019</td>
</tr>
<!-- ng-India 2019-->
<tr>
<th><a href="https://www.ng-ind.com/" title="ng-India">ng-India</a></th>
<td>Gurgaon, India</td>
<td>February 23, 2019</td>
</tr>
<!-- ngAtlanta 2019 -->
<tr>
<th><a href="https://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 9-12, 2019</td>
</tr>
<!-- AngularConnect-->
<tr>
<th>
<a href="https://past.angularconnect.com/2018" title="AngularConnect">AngularConnect</a>
</th>
<td>London, United Kingdom</td>
<td>November 5-7, 2018</td>
</tr>
<!-- ReactiveConf -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 29-31, 2018</td>
</tr>
<!-- AngularMix -->
<tr>
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>
<td>Orlando, Florida</td>
<td>October 10-12, 2018</td>
</tr>
<!-- Angular Conf Australia-->
<tr>
<th>
<a href="https://www.angularconf.com.au/" title="Angular Conf Australia">Angular Conf Australia</a>
</th>
<td>Melbourne, Australia</td>
<td>Jun 22, 2018</td>
</tr>
<!-- ngJapan-->
<tr>
<th><a href="https://ngjapan.org/en.html" title="ng-japan">ng-japan</a></th>
<td>Tokyo, Japan</td>
<td>Jun 16, 2018</td>
</tr>
<!-- WeRDevs-->
<tr>
<th><a href="https://www.wearedevelopers.com/" title="WeAreDevs">WeAreDevelopers</a></th>
<td>Vienna, Austria</td>
<td>May 16-18, 2018</td>
</tr>
<!-- ngconf 2018-->
<tr>
<th><a href="https://www.ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 18-20, 2018</td>
</tr>
<!-- ngVikings-->
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Helsinki, Finland</td>
<td>March 1-2, 2018</td>
</tr>
<!-- ngAtlanta-->
<tr>
<th><a href="http://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 30, 2018</td>
</tr>
</tbody>
</table>
</article> </article>

View File

@ -0,0 +1,228 @@
[
{
"name": "ngVikings",
"location": "Oslo, Norway",
"linkUrl": "https://ngvikings.org/",
"tooltip": "ngVikings",
"date": {
"start": "2020-05-25",
"end": "2020-05-26"
},
"workshopsDate": {
"start": "2020-05-27",
"end": "2020-05-27"
}
},
{
"name": "ng-conf",
"location": "Salt Lake City, Utah",
"linkUrl": "https://ng-conf.org/",
"tooltip": "ng-conf",
"date": {
"start": "2020-04-01",
"end": "2020-04-03"
}
},
{
"name": "ngIndia",
"location": "Delhi, India",
"linkUrl": "https://www.ng-ind.com/",
"tooltip": "ngIndia",
"date": {
"start": "2020-02-29",
"end": "2020-02-29"
}
},
{
"name": "ReactiveConf",
"location": "Prague, Czech Republic",
"linkUrl": "https://reactiveconf.com/",
"tooltip": "ReactiveConf",
"date": {
"start": "2019-10-30",
"end": "2019-11-01"
}
},
{
"name": "NG Rome MMXIX",
"location": "Rome, Italy",
"linkUrl": "https://ngrome.io",
"tooltip": "NG Rome MMXIX - The Italian Angular Conference",
"date": {
"start": "2019-10-07",
"end": "2019-10-07"
},
"workshopsDate": {
"start": "2019-10-06",
"end": "2019-10-06"
}
},
{
"name": "AngularConnect",
"location": "London, UK",
"linkUrl": "https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral",
"tooltip": "AngularConnect",
"date": {
"start": "2019-09-19",
"end": "2019-09-20"
}
},
{
"name": "NG-DE",
"location": "Berlin, Germany",
"linkUrl": "https://ng-de.org/",
"tooltip": "NG-DE",
"date": {
"start": "2019-08-30",
"end": "2019-08-31"
},
"workshopsDate": {
"start": "2019-08-29",
"end": "2019-08-29"
}
},
{
"name": "ng-japan",
"location": "Tokyo, Japan",
"linkUrl": "https://ngjapan.org/",
"tooltip": "ng-japan",
"date": {
"start": "2019-07-13",
"end": "2019-07-13"
}
},
{
"name": "ngVikings",
"location": "Copenhagen, Denmark",
"linkUrl": "https://ngvikings.org/",
"tooltip": "ngVikings",
"date": {
"start": "2019-05-27",
"end": "2019-05-28"
},
"workshopsDate": {
"start": "2019-05-26",
"end": "2019-05-26"
}
},
{
"name": "ng-conf",
"location": "Salt Lake City, Utah",
"linkUrl": "https://ng-conf.org/",
"tooltip": "ng-conf",
"date": {
"start": "2019-05-01",
"end": "2019-05-03"
}
},
{
"name": "ng-India",
"location": "Gurgaon, India",
"linkUrl": "https://www.ng-ind.com/",
"tooltip": "ng-India",
"date": {
"start": "2019-02-23",
"end": "2019-02-23"
}
},
{
"name": "ngAtlanta",
"location": "Atlanta, Georgia",
"linkUrl": "https://ng-atl.org/",
"tooltip": "ngAtlanta",
"date": {
"start": "2019-01-09",
"end": "2019-01-12"
}
},
{
"name": "AngularConnect",
"location": "London, United Kingdom",
"linkUrl": "https://past.angularconnect.com/2018",
"tooltip": "AngularConnect",
"date": {
"start": "2018-11-05",
"end": "2018-11-07"
}
},
{
"name": "ReactiveConf",
"location": "Prague, Czech Republic",
"linkUrl": "https://reactiveconf.com/",
"tooltip": "ReactiveConf",
"date": {
"start": "2018-10-29",
"end": "2018-10-31"
}
},
{
"name": "AngularMix",
"location": "Orlando, Florida",
"linkUrl": "https://angularmix.com/",
"tooltip": "AngularMix",
"date": {
"start": "2018-10-10",
"end": "2018-10-12"
}
},
{
"name": "Angular Conf Australia",
"location": "Melbourne, Australia",
"linkUrl": "https://www.angularconf.com.au/",
"tooltip": "Angular Conf Australia",
"date": {
"start": "2018-06-22",
"end": "2018-06-22"
}
},
{
"name": "ng-japan",
"location": "Tokyo, Japan",
"linkUrl": "https://ngjapan.org/en.html",
"tooltip": "ng-japan",
"date": {
"start": "2018-06-16",
"end": "2018-06-16"
}
},
{
"name": "WeAreDevelopers",
"location": "Vienna, Austria",
"linkUrl": "https://www.wearedevelopers.com/",
"tooltip": "WeAreDevs",
"date": {
"start": "2018-05-16",
"end": "2018-05-18"
}
},
{
"name": "ng-conf",
"location": "Salt Lake City, Utah",
"linkUrl": "https://ng-conf.org/",
"tooltip": "ng-conf",
"date": {
"start": "2018-04-18",
"end": "2018-04-20"
}
},
{
"name": "ngVikings",
"location": "Helsinki, Finland",
"linkUrl": "https://ngvikings.org/",
"tooltip": "ngVikings",
"date": {
"start": "2018-03-01",
"end": "2018-03-02"
}
},
{
"name": "ngAtlanta",
"location": "Atlanta, Georgia",
"linkUrl": "https://ng-atl.org/",
"tooltip": "ngAtlanta",
"date": {
"start": "2018-01-30",
"end": "2018-01-30"
}
}
]

View File

@ -40,6 +40,10 @@ export const ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES = [
{ {
selector: 'live-example', selector: 'live-example',
loadChildren: () => import('./live-example/live-example.module').then(m => m.LiveExampleModule) loadChildren: () => import('./live-example/live-example.module').then(m => m.LiveExampleModule)
},
{
selector: 'aio-events',
loadChildren: () => import('./events/events.module').then(m => m.EventsModule)
} }
]; ];

View File

@ -0,0 +1,43 @@
<p>Where we'll be presenting:</p>
<table class="is-full-width">
<thead>
<tr>
<th>Event</th>
<th>Location</th>
<th>Date</th>
</tr>
</thead>
<tbody >
<tr *ngFor="let event of upcomingEvents">
<th><a href="{{event.linkUrl}}" title="{{event.tooltip}}">{{event.name}}</a></th>
<td>{{event.location}}</td>
<td>
<div>
{{getEventDates(event)}}
</div>
</td>
</tr>
</tbody>
</table>
<p>Where we already presented:</p>
<table class="is-full-width">
<thead>
<tr>
<th>Event</th>
<th>Location</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let event of pastEvents">
<th><a href="{{event.linkUrl}}" title="{{event.tooltip}}">{{event.name}}</a></th>
<td>{{event.location}}</td>
<td>
<div>
{{getEventDates(event)}}
</div>
</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,295 @@
import { EventsComponent } from './events.component';
import { EventsService } from './events.service';
import { Event } from './events.component';
import { ReflectiveInjector } from '@angular/core';
import { Subject } from 'rxjs';
describe('EventsComponent', () => {
let component: EventsComponent;
let injector: ReflectiveInjector;
let eventsService: TestEventService;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
EventsComponent,
{provide: EventsService, useClass: TestEventService },
]);
eventsService = injector.get(EventsService) as any;
component = injector.get(EventsComponent);
component.ngOnInit();
});
it('should have no pastEvents when first created', () => {
expect(component.pastEvents).toBeUndefined();
});
it('should have no upcoming when first created', () => {
expect(component.upcomingEvents).toBeUndefined();
});
describe('ngOnInit', () => {
it('should have 2 upcoming events', () => {
eventsService.events.next([{
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2099-07-25',
'end': '2099-07-26'
},
'workshopsDate': {
'start': '2099-07-27',
'end': '2099-07-27'
}
},
{
'location': 'Salt Lake City, Utah',
'tooltip': 'ng-conf',
'linkUrl': 'https://ng-conf.org/',
'name': 'ng-conf ',
'date': {
'start': '2099-06-20',
'end': '2099-06-20'
}
},
{
'location': 'Delhi, India',
'tooltip': 'ngIndia',
'linkUrl': 'https://www.ng-ind.com/',
'name': 'ngIndia',
'date': {
'start': '2020-02-29',
'end': '2020-02-29'
}
}]);
expect(component.upcomingEvents.length).toEqual(2);
});
it('should have 4 past events', () => {
eventsService.events.next([
{
'location': 'Salt Lake City, Utah',
'tooltip': 'ng-conf',
'linkUrl': 'https://ng-conf.org/',
'name': 'ng-conf ',
'date': {
'start': '2099-06-20',
'end': '2099-06-20'
}
},
{
'location': 'Rome, Italy',
'tooltip': 'NG Rome MMXIX - The Italian Angular Conference',
'linkUrl': 'https://ngrome.io',
'name': 'NG Rome MMXIX',
'date': {
'start': '2019-10-07',
'end': '2019-10-07'
},
'workshopsDate': {
'start': '2019-10-06',
'end': '2019-10-06'
}
},
{
'location': 'London, UK',
'tooltip': 'AngularConnect',
'linkUrl': 'https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral',
'name': 'AngularConnect',
'date': {
'start': '2019-09-19',
'end': '2019-09-20'
}
},
{
'location': 'Berlin, Germany',
'tooltip': 'NG-DE',
'linkUrl': 'https://ng-de.org/',
'name': 'NG-DE',
'date': {
'start': '2019-08-30',
'end': '2019-08-31'
},
'workshopsDate': {
'start': '2019-08-29',
'end': '2019-08-29'
}
},
{
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2018-07-26',
'end': '2018-07-26'
},
'workshopsDate': {
'start': '2018-07-27',
'end': '2018-07-27'
}
}]);
expect(component.pastEvents.length).toEqual(4);
});
});
describe('Getting event dates if no workshop date', () => {
it('should return only conference date', () => {
const datestring = component.getEventDates({
'location': 'Salt Lake City, Utah',
'tooltip': 'ng-conf',
'linkUrl': 'https://ng-conf.org/',
'name': 'ng-conf ',
'date': {
'start': '2020-06-20',
'end': '2020-06-20'
}
});
expect(datestring).toEqual('June 20, 2020');
});
it('should return only conference date with changing months if date is in two diffrent months', () => {
const datestring = component.getEventDates({
'location': 'Prague, Czech Republic',
'tooltip': 'ReactiveConf',
'linkUrl': 'https://reactiveconf.com/',
'name': 'ReactiveConf',
'date': {
'start': '2019-10-30',
'end': '2019-11-01'
}
});
expect(datestring).toEqual('October 30 - November 1, 2019');
});
it('should return only conference date with "- lastdate" if conference over multiple days', () => {
const datestring = component.getEventDates({
'location': 'London, UK',
'tooltip': 'AngularConnect',
'linkUrl': 'https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral',
'name': 'AngularConnect',
'date': {
'start': '2019-09-19',
'end': '2019-09-20'
}
});
expect(datestring).toEqual('September 19-20, 2019');
});
});
describe('Getting event dates if workshop date', () => {
it('should return conference date with different days, workshopdate', () => {
const datestring = component.getEventDates({
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2020-07-25',
'end': '2020-07-26'
},
'workshopsDate': {
'start': '2020-07-27',
'end': '2020-07-27'
}
});
expect(datestring).toEqual('July 25-26 (conference), July 27 (workshops), 2020');
});
it('should return workshop date, conference date if workshop before conf date', () => {
const datestring = component.getEventDates({
'location': 'Rome, Italy',
'tooltip': 'NG Rome MMXIX - The Italian Angular Conference',
'linkUrl': 'https://ngrome.io',
'name': 'NG Rome MMXIX',
'date': {
'start': '2019-10-07',
'end': '2019-10-07'
},
'workshopsDate': {
'start': '2019-10-06',
'end': '2019-10-06'
}
});
expect(datestring).toEqual('October 6 (workshops), October 7 (conference), 2019');
});
it('should return workshop date, conference date if workshop before conference date', () => {
const datestring = component.getEventDates({
'location': 'Berlin, Germany',
'tooltip': 'NG-DE',
'linkUrl': 'https://ng-de.org/',
'name': 'NG-DE',
'date': {
'start': '2019-08-30',
'end': '2019-08-31'
},
'workshopsDate': {
'start': '2019-08-29',
'end': '2019-08-29'
}
});
expect(datestring).toEqual('August 29 (workshops), August 30-31 (conference), 2019');
});
it('should return only conference date, wokshop date if workshop after conference', () => {
const datestring = component.getEventDates({
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2018-07-26',
'end': '2018-07-26'
},
'workshopsDate': {
'start': '2018-07-27',
'end': '2018-07-27'
}
});
expect(datestring).toEqual('July 26 (conference), July 27 (workshops), 2018');
});
it('should return conference date and workshop date with different days and months, starting with confrence date', () => {
const datestring = component.getEventDates({
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2020-07-30',
'end': '2020-07-31'
},
'workshopsDate': {
'start': '2020-08-01',
'end': '2020-08-02'
}
});
expect(datestring).toEqual('July 30-31 (conference), August 1-2 (workshops), 2020');
});
it('should return conference date and workshop date with different days and months, starting with workshopdate', () => {
const datestring = component.getEventDates({
'location': 'Oslo, Norway',
'tooltip': 'ngVikings',
'linkUrl': 'https://ngvikings.org/',
'name': 'ngVikings',
'date': {
'start': '2020-08-01',
'end': '2020-08-02'
},
'workshopsDate': {
'start': '2020-07-30',
'end': '2020-07-31'
}
});
expect(datestring).toEqual('July 30-31 (workshops), August 1-2 (conference), 2020');
});
});
});
class TestEventService {
events = new Subject<Event[]>();
}

View File

@ -0,0 +1,102 @@
import { Component, OnInit } from '@angular/core';
import { EventsService } from './events.service';
const DAY = 24 * 60 * 60 * 1000;
const MONTHS = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
type date = string; // of the format `YYYY-MM-DD`.
interface Duration {
start: date;
end: date;
}
export interface Event {
name: string;
location: string;
linkUrl: string;
tooltip?: string;
date: Duration;
workshopsDate?: Duration;
}
@Component({
selector: 'aio-events',
templateUrl: 'events.component.html'
})
export class EventsComponent implements OnInit {
pastEvents: Event[];
upcomingEvents: Event[];
constructor(private eventsService: EventsService) { }
ngOnInit() {
this.eventsService.events.subscribe(events => {
this.pastEvents = events
.filter(event => new Date(event.date.end).getTime() < Date.now() - DAY)
.sort((l: Event, r: Event) => isBefore(l.date, r.date) ? 1 : -1);
this.upcomingEvents = events
.filter(event => new Date(event.date.end).getTime() >= Date.now() - DAY)
.sort((l: Event, r: Event) => isBefore(l.date, r.date) ? -1 : 1);
});
}
getEventDates(event: Event) {
let dateString;
// Check if there is a workshop
if (event.workshopsDate) {
const mainEventDateString = `${processDate(event.date)} (conference)`;
const workshopsDateString = `${processDate(event.workshopsDate)} (workshops)`;
const areWorkshopsBeforeEvent = isBefore(event.workshopsDate, event.date);
dateString = areWorkshopsBeforeEvent ?
`${workshopsDateString}, ${mainEventDateString}` :
`${mainEventDateString}, ${workshopsDateString}`;
} else {
// If no work shop date create conference date string
dateString = processDate(event.date);
}
dateString = `${dateString}, ${new Date(event.date.end).getFullYear()}`;
return dateString;
}
}
function processDate(dates: Duration) {
// Covert Date sting to date object for comparisons
const startDate = new Date(dates.start);
const endDate = new Date(dates.end);
// Create a date string in the start like January 31
let processedDate = `${MONTHS[startDate.getMonth()]} ${startDate.getDate()}`;
// If they are in different months add the string '- February 2' Making the final string January 31 - February 2
if (startDate.getMonth() !== endDate.getMonth()) {
processedDate = `${processedDate} - ${MONTHS[endDate.getMonth()]} ${endDate.getDate()}`;
} else if (startDate.getDate() !== endDate.getDate()) {
// If not add - date eg it will make // January 30-31
processedDate = `${processedDate}-${endDate.getDate()}`;
}
return processedDate;
}
function isBefore(duration1: Duration, duration2: Duration): boolean {
return (duration1.start < duration2.start) ||
(duration1.start === duration2.start && duration1.end < duration2.end);
}

View File

@ -0,0 +1,15 @@
import { NgModule, Type } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EventsComponent } from './events.component';
import { EventsService } from './events.service';
import { WithCustomElementComponent } from '../element-registry';
@NgModule({
imports: [ CommonModule ],
declarations: [ EventsComponent ],
entryComponents: [ EventsComponent ],
providers: [ EventsService]
})
export class EventsModule implements WithCustomElementComponent {
customElementComponent: Type<any> = EventsComponent;
}

View File

@ -0,0 +1,56 @@
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { Injector } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { EventsService } from './events.service';
import { Logger } from 'app/shared/logger.service';
import { MockLogger } from 'testing/logger.service';
describe('EventsService', () => {
let injector: Injector;
let eventsService: EventsService;
let httpMock: HttpTestingController;
let mockLogger: MockLogger;
beforeEach(() => {
injector = TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
EventsService,
{ provide: Logger, useClass: MockLogger }
]
});
eventsService = injector.get<EventsService>(EventsService);
mockLogger = injector.get(Logger) as any;
httpMock = injector.get(HttpTestingController);
});
afterEach(() => httpMock.verify());
it('should make a single connection to the server', () => {
eventsService.events.subscribe();
eventsService.events.subscribe();
httpMock.expectOne('generated/events.json');
expect().nothing(); // Prevent jasmine from complaining about no expectations.
});
it('should handle a failed request for `events.json`', () => {
const request = httpMock.expectOne('generated/events.json');
request.error(new ErrorEvent('404'));
expect(mockLogger.output.error).toEqual([
[jasmine.any(Error)]
]);
expect(mockLogger.output.error[0][0].message).toMatch(/^generated\/events\.json request failed:/);
});
it('should return an empty array on a failed request for `events.json`', done => {
const request = httpMock.expectOne('generated/events.json');
request.error(new ErrorEvent('404'));
eventsService.events.subscribe(results => {
expect(results).toEqual([]);
done();
});
});
});

View File

@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ConnectableObservable, Observable, of } from 'rxjs';
import { catchError, publishLast } from 'rxjs/operators';
import { Event } from './events.component';
import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
import { Logger } from 'app/shared/logger.service';
const eventsPath = CONTENT_URL_PREFIX + 'events.json';
@Injectable()
export class EventsService {
events: Observable<Event[]>;
constructor(private http: HttpClient, private logger: Logger) {
this.events = this.getEvents();
}
private getEvents() {
const events = this.http.get<any>(eventsPath).pipe(
catchError(error => {
this.logger.error(new Error(`${eventsPath} request failed: ${error.message}`));
return of([]);
}),
publishLast()
);
(events as ConnectableObservable<Event[]>).connect();
return events;
}
}

View File

@ -5,6 +5,7 @@ module.exports = function createSitemap() {
'contributors-json', 'contributors-json',
'navigation-json', 'navigation-json',
'resources-json', 'resources-json',
'events-json'
], ],
ignoredPaths: [ ignoredPaths: [
'file-not-found', 'file-not-found',

View File

@ -82,6 +82,11 @@ module.exports = new Package('angular-content', [basePackage, contentPackage])
include: CONTENTS_PATH + '/marketing/resources.json', include: CONTENTS_PATH + '/marketing/resources.json',
fileReader: 'jsonFileReader' fileReader: 'jsonFileReader'
}, },
{
basePath: CONTENTS_PATH,
include: CONTENTS_PATH + '/marketing/events.json',
fileReader: 'jsonFileReader'
},
]); ]);
collectExamples.exampleFolders.push('examples'); collectExamples.exampleFolders.push('examples');
@ -110,7 +115,8 @@ module.exports = new Package('angular-content', [basePackage, contentPackage])
{docTypes: ['navigation-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}, {docTypes: ['navigation-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
{docTypes: ['contributors-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}, {docTypes: ['contributors-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
{docTypes: ['announcements-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}, {docTypes: ['announcements-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
{docTypes: ['resources-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'} {docTypes: ['resources-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'},
{docTypes: ['events-json'], pathTemplate: '${id}', outputPathTemplate: '../${id}.json'}
]); ]);
}) })

View File

@ -2,8 +2,8 @@
"aio": { "aio": {
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 2987, "runtime-es2015": 3037,
"main-es2015": 450880, "main-es2015": 450952,
"polyfills-es2015": 52685 "polyfills-es2015": 52685
} }
} }
@ -11,18 +11,18 @@
"aio-local": { "aio-local": {
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 2987, "runtime-es2015": 3037,
"main-es2015": 448419, "main-es2015": 448493,
"polyfills-es2015": 52630 "polyfills-es2015": 52415
} }
} }
}, },
"aio-local-viewengine": { "aio-local-viewengine": {
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 3097, "runtime-es2015": 3157,
"main-es2015": 430239, "main-es2015": 430008,
"polyfills-es2015": 52195 "polyfills-es2015": 52415
} }
} }
} }