Update
This commit is contained in:
parent
1f5fae51f2
commit
46d8f3f856
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,9 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# CAVALLIUM SPECIFIC
|
||||||
|
*.generated.html
|
||||||
|
angular.json
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
/tmp
|
/tmp
|
||||||
|
12
angular.json
12
angular.json
@ -27,7 +27,8 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss",
|
||||||
|
"src/styles-fonts.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"es5BrowserSupport": true,
|
"es5BrowserSupport": true,
|
||||||
@ -58,13 +59,14 @@
|
|||||||
"maximumError": "5mb"
|
"maximumError": "5mb"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index": "src/index.it.generated.html",
|
||||||
"outputPath": "dist/italian/",
|
"outputPath": "dist/italian/",
|
||||||
"i18nFile": "src/locale/messages.it.xlf",
|
"i18nFile": "src/locale/messages.it.xlf",
|
||||||
"i18nLocale": "it"
|
"i18nLocale": "it"
|
||||||
},
|
},
|
||||||
"serve_it": {
|
"serve_it": {
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"baseHref": "/it/",
|
"index": "src/index.it.generated.html",
|
||||||
"outputPath": "dist/italian/",
|
"outputPath": "dist/italian/",
|
||||||
"i18nFile": "src/locale/messages.it.xlf",
|
"i18nFile": "src/locale/messages.it.xlf",
|
||||||
"i18nLocale": "it"
|
"i18nLocale": "it"
|
||||||
@ -92,13 +94,14 @@
|
|||||||
"maximumError": "5mb"
|
"maximumError": "5mb"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index": "src/index.en.generated.html",
|
||||||
"outputPath": "dist/english/",
|
"outputPath": "dist/english/",
|
||||||
"i18nFile": "src/locale/messages.en.xlf",
|
"i18nFile": "src/locale/messages.en.xlf",
|
||||||
"i18nLocale": "en"
|
"i18nLocale": "en"
|
||||||
},
|
},
|
||||||
"serve_en": {
|
"serve_en": {
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"baseHref": "/en/",
|
"index": "src/index.en.generated.html",
|
||||||
"outputPath": "dist/english/",
|
"outputPath": "dist/english/",
|
||||||
"i18nFile": "src/locale/messages.en.xlf",
|
"i18nFile": "src/locale/messages.en.xlf",
|
||||||
"i18nLocale": "en"
|
"i18nLocale": "en"
|
||||||
@ -138,7 +141,8 @@
|
|||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
"karmaConfig": "src/karma.conf.js",
|
"karmaConfig": "src/karma.conf.js",
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss",
|
||||||
|
"src/styles-fonts.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"assets": [
|
"assets": [
|
||||||
|
25
build.js
25
build.js
@ -1,3 +1,5 @@
|
|||||||
|
#! /usr/bin/env node
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const { spawn } = require('cross-spawn');
|
const { spawn } = require('cross-spawn');
|
||||||
var execOptions = {
|
var execOptions = {
|
||||||
@ -7,26 +9,39 @@ var execOptions = {
|
|||||||
const argument0 = process.argv[2];
|
const argument0 = process.argv[2];
|
||||||
|
|
||||||
async function main(runMode) {
|
async function main(runMode) {
|
||||||
const angularSourceText = fs.readFileSync("buildconfig.json");
|
const angularSourceBuffer = fs.readFileSync("buildconfig.json");
|
||||||
const angularSource = JSON.parse(angularSourceText);
|
const angularSource = JSON.parse(angularSourceBuffer);
|
||||||
const productionConfiguration = angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production"];
|
const productionConfiguration = angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production"];
|
||||||
delete angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production"];
|
delete angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production"];
|
||||||
angularSource.languages.forEach((language, languageIndex) => {
|
angularSource.languages.forEach((language, languageIndex) => {
|
||||||
const languageConfiguration = angularSource.angular.projects[angularSource.projectName].architect.build.configurations[language];
|
const defaultIndex = angularSource.angular.projects[angularSource.projectName].architect.build.options.index;
|
||||||
|
const defaultIndexName = defaultIndex.split(".").slice(0, -1).join(".");
|
||||||
|
const defaultIndexExtension = defaultIndex.split(".").pop();
|
||||||
|
const languageSpecificIndex = defaultIndexName + "." + language + ".generated." + defaultIndexExtension;
|
||||||
|
|
||||||
|
const languageConfiguration = {
|
||||||
|
"index": languageSpecificIndex,
|
||||||
|
...angularSource.angular.projects[angularSource.projectName].architect.build.configurations[language]
|
||||||
|
};
|
||||||
delete angularSource.angular.projects[angularSource.projectName].architect.build.configurations[language];
|
delete angularSource.angular.projects[angularSource.projectName].architect.build.configurations[language];
|
||||||
|
|
||||||
angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production_" + language] = {
|
angularSource.angular.projects[angularSource.projectName].architect.build.configurations["production_" + language] = {
|
||||||
...productionConfiguration,
|
...productionConfiguration,
|
||||||
...languageConfiguration
|
...languageConfiguration
|
||||||
};
|
};
|
||||||
angularSource.angular.projects[angularSource.projectName].architect.build.configurations["serve_" + language] = {
|
angularSource.angular.projects[angularSource.projectName].architect.build.configurations["serve_" + language] = {
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"baseHref": "/"+language+"/",
|
|
||||||
...languageConfiguration,
|
...languageConfiguration,
|
||||||
};
|
};
|
||||||
angularSource.angular.projects[angularSource.projectName].architect.serve.configurations[language] = {
|
angularSource.angular.projects[angularSource.projectName].architect.serve.configurations[language] = {
|
||||||
"browserTarget": "cavallium-website:build:serve_"+language,
|
"browserTarget": "cavallium-website:build:serve_"+language,
|
||||||
"port": 4200 + languageIndex
|
"port": 4200 + languageIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create index.language.html
|
||||||
|
let indexText = fs.readFileSync(defaultIndex).toString("utf8");
|
||||||
|
indexText = indexText.replace("<html>", "<html lang=\"" + language + "\">");
|
||||||
|
fs.writeFileSync(languageSpecificIndex, indexText);
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.writeFileSync("angular.json", JSON.stringify(angularSource.angular, null, "\t"), "utf8");
|
fs.writeFileSync("angular.json", JSON.stringify(angularSource.angular, null, "\t"), "utf8");
|
||||||
@ -45,7 +60,7 @@ async function main(runMode) {
|
|||||||
case "serve":
|
case "serve":
|
||||||
await Promise.all(angularSource.languages.map((language, index) => {
|
await Promise.all(angularSource.languages.map((language, index) => {
|
||||||
console.log("Building for language " + JSON.stringify(language) + (index > 0 ? " (hidden)" : ""));
|
console.log("Building for language " + JSON.stringify(language) + (index > 0 ? " (hidden)" : ""));
|
||||||
const childProcess = spawn("ng", ["serve", "--configuration=" + language],
|
const childProcess = spawn("ng", ["serve", "--configuration=" + language, "--host=0.0.0.0"],
|
||||||
{ stdio: [process.stdin, index == 0 ? process.stdout : null, process.stderr] });
|
{ stdio: [process.stdin, index == 0 ? process.stdout : null, process.stderr] });
|
||||||
return onExit(childProcess);
|
return onExit(childProcess);
|
||||||
}));
|
}));
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss",
|
||||||
|
"src/styles-fonts.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"es5BrowserSupport": true,
|
"es5BrowserSupport": true,
|
||||||
@ -106,7 +107,8 @@
|
|||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
"karmaConfig": "src/karma.conf.js",
|
"karmaConfig": "src/karma.conf.js",
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss",
|
||||||
|
"src/styles-fonts.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"assets": [
|
"assets": [
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { AppPage } from './app.po';
|
import { AppPage } from "./app.po";
|
||||||
import { browser, logging } from 'protractor';
|
import { browser, logging } from "protractor";
|
||||||
|
|
||||||
describe('workspace-project App', () => {
|
describe("workspace-project App", () => {
|
||||||
let page: AppPage;
|
let page: AppPage;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
page = new AppPage();
|
page = new AppPage();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
it("should display welcome message", () => {
|
||||||
page.navigateTo();
|
page.navigateTo();
|
||||||
expect(page.getTitleText()).toEqual('Welcome to cavallium-website!');
|
expect(page.getTitleText()).toEqual("Welcome to cavallium-website!");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
import { browser, by, element } from "protractor";
|
||||||
|
|
||||||
export class AppPage {
|
export class AppPage {
|
||||||
navigateTo() {
|
navigateTo() {
|
||||||
@ -6,6 +6,6 @@ export class AppPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTitleText() {
|
getTitleText() {
|
||||||
return element(by.css('app-root h1')).getText() as Promise<string>;
|
return element(by.css("app-root h1")).getText() as Promise<string>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "node build.js serve",
|
"start": "node build.js serve",
|
||||||
|
"serve": "node build.js serve",
|
||||||
"build": "node build.js build",
|
"build": "node build.js build",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from "@angular/core";
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from "@angular/router";
|
||||||
|
import { ArticleComponent } from "./article/article.component";
|
||||||
|
import { RouterEmptyComponent } from "./gui/router-empty/router-empty.component";
|
||||||
|
|
||||||
const routes: Routes = [];
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: "article",
|
||||||
|
component: RouterEmptyComponent,
|
||||||
|
children: [{
|
||||||
|
path: "**",
|
||||||
|
component: ArticleComponent
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
|
@ -1,22 +1,8 @@
|
|||||||
<!--The content below is only a placeholder and can be replaced.-->
|
<nav>
|
||||||
<div style="text-align:center">
|
<app-navbar></app-navbar>
|
||||||
<h1>
|
</nav>
|
||||||
|
<h1>
|
||||||
Welcome to {{ title }}!
|
Welcome to {{ title }}!
|
||||||
</h1>
|
</h1>
|
||||||
<p i18n="@@introductionHeader">Welcome to</p>
|
<p i18n="@@introductionHeader">Welcome to</p>
|
||||||
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
|
|
||||||
</div>
|
|
||||||
<h2>Here are some links to help you start: </h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://angular.io/cli">CLI Documentation</a></h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { TestBed, async } from '@angular/core/testing';
|
import { TestBed, async } from "@angular/core/testing";
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from "@angular/router/testing";
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from "./app.component";
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
describe("AppComponent", () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -14,7 +14,7 @@ describe('AppComponent', () => {
|
|||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should create the app', () => {
|
it("should create the app", () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.debugElement.componentInstance;
|
const app = fixture.debugElement.componentInstance;
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
@ -23,13 +23,13 @@ describe('AppComponent', () => {
|
|||||||
it(`should have as title 'cavallium-website'`, () => {
|
it(`should have as title 'cavallium-website'`, () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.debugElement.componentInstance;
|
const app = fixture.debugElement.componentInstance;
|
||||||
expect(app.title).toEqual('cavallium-website');
|
expect(app.title).toEqual("cavallium-website");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render title in a h1 tag', () => {
|
it("should render title in a h1 tag", () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to cavallium-website!');
|
expect(compiled.querySelector("h1").textContent).toContain("Welcome to cavallium-website!");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: "app-root",
|
||||||
templateUrl: './app.component.html',
|
templateUrl: "./app.component.html",
|
||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ["./app.component.scss"]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'cavallium-website';
|
title = "cavallium-website";
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from "@angular/platform-browser";
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from "@angular/core";
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from "./app-routing.module";
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from "./app.component";
|
||||||
import { HomeComponent } from './pages/home/home.component';
|
import { HomeComponent } from "./pages/home/home.component";
|
||||||
import { NavbarComponent } from './gui/navbar/navbar.component';
|
import { NavbarComponent } from "./gui/navbar/navbar.component";
|
||||||
import { FooterComponent } from './gui/footer/footer.component';
|
import { FooterComponent } from "./gui/footer/footer.component";
|
||||||
|
import { ArticleComponent } from "./article/article.component";
|
||||||
|
import { RouterEmptyComponent } from "./gui/router-empty/router-empty.component";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
NavbarComponent,
|
NavbarComponent,
|
||||||
FooterComponent
|
FooterComponent,
|
||||||
|
ArticleComponent,
|
||||||
|
RouterEmptyComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
3
src/app/article/article.component.html
Normal file
3
src/app/article/article.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
article works!
|
||||||
|
</p>
|
0
src/app/article/article.component.scss
Normal file
0
src/app/article/article.component.scss
Normal file
25
src/app/article/article.component.spec.ts
Normal file
25
src/app/article/article.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
|
import { ArticleComponent } from "./article.component";
|
||||||
|
|
||||||
|
describe("ArticleComponent", () => {
|
||||||
|
let component: ArticleComponent;
|
||||||
|
let fixture: ComponentFixture<ArticleComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ArticleComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ArticleComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create", () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
19
src/app/article/article.component.ts
Normal file
19
src/app/article/article.component.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { ActivatedRoute, UrlSegment } from "@angular/router";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-article",
|
||||||
|
templateUrl: "./article.component.html",
|
||||||
|
styleUrls: ["./article.component.scss"]
|
||||||
|
})
|
||||||
|
export class ArticleComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(private activatedRoute: ActivatedRoute) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.activatedRoute.data.subscribe(console.log);
|
||||||
|
this.activatedRoute.params.subscribe(console.log);
|
||||||
|
this.activatedRoute.url.subscribe((url: UrlSegment[]) => console.log(url.map((urlSegment) => urlSegment.path).join("/")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
import { FooterComponent } from './footer.component';
|
import { FooterComponent } from "./footer.component";
|
||||||
|
|
||||||
describe('FooterComponent', () => {
|
describe("FooterComponent", () => {
|
||||||
let component: FooterComponent;
|
let component: FooterComponent;
|
||||||
let fixture: ComponentFixture<FooterComponent>;
|
let fixture: ComponentFixture<FooterComponent>;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ describe('FooterComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it("should create", () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-footer',
|
selector: "app-footer",
|
||||||
templateUrl: './footer.component.html',
|
templateUrl: "./footer.component.html",
|
||||||
styleUrls: ['./footer.component.scss']
|
styleUrls: ["./footer.component.scss"]
|
||||||
})
|
})
|
||||||
export class FooterComponent implements OnInit {
|
export class FooterComponent implements OnInit {
|
||||||
|
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
<p>
|
<div class="big-logo">
|
||||||
navbar works!
|
<h1>Big Logo</h1>
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
|
<div class="header-logo-large">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="header-logo">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="header-nav">
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let link of navigationLinks">
|
||||||
|
<a *ngIf="link.external === true" [href]="link.address" [target]="link.newtab === undefined || link.newtab === true ? '_blank' : '_self'">{{link.text}}</a>
|
||||||
|
<a *ngIf="link.external !== true" [routerLink]="link.address" [target]="link.newtab === true ? '_blank' : '_self'">{{link.text}}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
@ -1,8 +1,8 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
import { NavbarComponent } from './navbar.component';
|
import { NavbarComponent } from "./navbar.component";
|
||||||
|
|
||||||
describe('NavbarComponent', () => {
|
describe("NavbarComponent", () => {
|
||||||
let component: NavbarComponent;
|
let component: NavbarComponent;
|
||||||
let fixture: ComponentFixture<NavbarComponent>;
|
let fixture: ComponentFixture<NavbarComponent>;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ describe('NavbarComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it("should create", () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,35 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { NavigationLink } from "src/app/symbols/NavigationLink";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar',
|
selector: "app-navbar",
|
||||||
templateUrl: './navbar.component.html',
|
templateUrl: "./navbar.component.html",
|
||||||
styleUrls: ['./navbar.component.scss']
|
styleUrls: ["./navbar.component.scss"]
|
||||||
})
|
})
|
||||||
export class NavbarComponent implements OnInit {
|
export class NavbarComponent implements OnInit {
|
||||||
|
|
||||||
|
public navigationLinks: NavigationLink[] = [
|
||||||
|
{
|
||||||
|
text: "Software",
|
||||||
|
address: "/article/software"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Midi23D",
|
||||||
|
address: "/article/midi23d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Calculator",
|
||||||
|
address: "/article/calculator",
|
||||||
|
newtab: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Github",
|
||||||
|
address: "https://github.com/Cavallium/WarpPI",
|
||||||
|
external: true,
|
||||||
|
newtab: false
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
1
src/app/gui/router-empty/router-empty.component.html
Normal file
1
src/app/gui/router-empty/router-empty.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<router-outlet></router-outlet>
|
25
src/app/gui/router-empty/router-empty.component.spec.ts
Normal file
25
src/app/gui/router-empty/router-empty.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
|
import { RouterEmptyComponent } from "./router-empty.component";
|
||||||
|
|
||||||
|
describe("RouterEmptyComponent", () => {
|
||||||
|
let component: RouterEmptyComponent;
|
||||||
|
let fixture: ComponentFixture<RouterEmptyComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ RouterEmptyComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RouterEmptyComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create", () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
15
src/app/gui/router-empty/router-empty.component.ts
Normal file
15
src/app/gui/router-empty/router-empty.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-router-empty",
|
||||||
|
templateUrl: "./router-empty.component.html",
|
||||||
|
styleUrls: ["./router-empty.component.scss"]
|
||||||
|
})
|
||||||
|
export class RouterEmptyComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
import { HomeComponent } from './home.component';
|
import { HomeComponent } from "./home.component";
|
||||||
|
|
||||||
describe('HomeComponent', () => {
|
describe("HomeComponent", () => {
|
||||||
let component: HomeComponent;
|
let component: HomeComponent;
|
||||||
let fixture: ComponentFixture<HomeComponent>;
|
let fixture: ComponentFixture<HomeComponent>;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ describe('HomeComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it("should create", () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: "app-home",
|
||||||
templateUrl: './home.component.html',
|
templateUrl: "./home.component.html",
|
||||||
styleUrls: ['./home.component.scss']
|
styleUrls: ["./home.component.scss"]
|
||||||
})
|
})
|
||||||
export class HomeComponent implements OnInit {
|
export class HomeComponent implements OnInit {
|
||||||
|
|
||||||
|
12
src/app/services/document-fetch.service.spec.ts
Normal file
12
src/app/services/document-fetch.service.spec.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
|
import { DocumentFetchService } from "./document-fetch.service";
|
||||||
|
|
||||||
|
describe("DocumentFetchService", () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it("should be created", () => {
|
||||||
|
const service: DocumentFetchService = TestBed.get(DocumentFetchService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
44
src/app/services/document-fetch.service.ts
Normal file
44
src/app/services/document-fetch.service.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { DocumentData } from "../symbols/DocumentData";
|
||||||
|
import { HttpClient, Request, Response } from "selenium-webdriver/http";
|
||||||
|
import { encodeUriSegment } from "@angular/router/src/url_tree";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root"
|
||||||
|
})
|
||||||
|
export class DocumentFetchService {
|
||||||
|
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
public async fetch(unsafeId: string): Promise<DocumentData> {
|
||||||
|
const encodedId = this.encodeId(unsafeId);
|
||||||
|
const response: Response = await this.http.send(new Request("GET", "/documents/" + encodedId + ".md"));
|
||||||
|
if (response.status === 200) {
|
||||||
|
return {
|
||||||
|
found: true,
|
||||||
|
id: encodedId,
|
||||||
|
content: await response.body
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
found: false,
|
||||||
|
id: encodedId,
|
||||||
|
content: await this.fetchErrorContent(404)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async fetchErrorContent(errorCode: number): Promise<string> {
|
||||||
|
if (errorCode > 0 && errorCode <= 700) {
|
||||||
|
const response: Response = await this.http.send(new Request("GET", "/documents/" + errorCode + ".md"));
|
||||||
|
if (response.status === 200) {
|
||||||
|
return await response.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Error " + errorCode + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
private encodeId(id: string): string {
|
||||||
|
return id.split("/").map(encodeUriSegment).filter((part) => part !== "." && part !== "..").join("/");
|
||||||
|
}
|
||||||
|
}
|
5
src/app/symbols/DocumentData.ts
Normal file
5
src/app/symbols/DocumentData.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface DocumentData {
|
||||||
|
id: string;
|
||||||
|
content: string;
|
||||||
|
found: boolean;
|
||||||
|
}
|
6
src/app/symbols/NavigationLink.ts
Normal file
6
src/app/symbols/NavigationLink.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface NavigationLink {
|
||||||
|
address: string;
|
||||||
|
text: string;
|
||||||
|
external?: boolean;
|
||||||
|
newtab?: boolean;
|
||||||
|
}
|
BIN
src/assets/Muli-600i-latin.woff2
Normal file
BIN
src/assets/Muli-600i-latin.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-600i-latinext.woff2
Normal file
BIN
src/assets/Muli-600i-latinext.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-600r-latin.woff2
Normal file
BIN
src/assets/Muli-600r-latin.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-600r-latinext.woff2
Normal file
BIN
src/assets/Muli-600r-latinext.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-800i-latin.woff2
Normal file
BIN
src/assets/Muli-800i-latin.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-800i-latinext.woff2
Normal file
BIN
src/assets/Muli-800i-latinext.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-800r-latin.woff2
Normal file
BIN
src/assets/Muli-800r-latin.woff2
Normal file
Binary file not shown.
BIN
src/assets/Muli-800r-latinext.woff2
Normal file
BIN
src/assets/Muli-800r-latinext.woff2
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>CavalliumWebsite</title>
|
<title>CavalliumWebsite</title>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from "@angular/core";
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
import { AppModule } from "./app/app.module";
|
||||||
import { environment } from './environments/environment';
|
import { environment } from "./environments/environment";
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* Zone JS is required by default for Angular itself.
|
* Zone JS is required by default for Angular itself.
|
||||||
*/
|
*/
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
import "zone.js/dist/zone"; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
|
67
src/styles-fonts.scss
Normal file
67
src/styles-fonts.scss
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Muli SemiBold Italic'), local('Muli-SemiBoldItalic'), url(/assets/Muli-600i-latinext.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Muli SemiBold Italic'), local('Muli-SemiBoldItalic'), url(/assets/Muli-600i-latin.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Muli ExtraBold Italic'), local('Muli-ExtraBoldItalic'), url(/assets/Muli-800i-latinext.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Muli ExtraBold Italic'), local('Muli-ExtraBoldItalic'), url(/assets/Muli-800i-latin.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Muli SemiBold'), local('Muli-SemiBold'), url(/assets/Muli-600r-latinext.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Muli SemiBold'), local('Muli-SemiBold'), url(/assets/Muli-600r-latin.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Muli ExtraBold'), local('Muli-ExtraBold'), url(/assets/Muli-800r-latinext.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Muli-custom';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Muli ExtraBold'), local('Muli-ExtraBold'), url(/assets/Muli-800r-latin.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
@ -1 +1,9 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Muli-custom", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
strong, b, h1, h2, h3, h4, h5, h6, th {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
import 'zone.js/dist/zone-testing';
|
import "zone.js/dist/zone-testing";
|
||||||
import { getTestBed } from '@angular/core/testing';
|
import { getTestBed } from "@angular/core/testing";
|
||||||
import {
|
import {
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
} from "@angular/platform-browser-dynamic/testing";
|
||||||
|
|
||||||
declare const require: any;
|
declare const require: any;
|
||||||
|
|
||||||
@ -15,6 +15,6 @@ getTestBed().initTestEnvironment(
|
|||||||
platformBrowserDynamicTesting()
|
platformBrowserDynamicTesting()
|
||||||
);
|
);
|
||||||
// Then we find all the tests.
|
// Then we find all the tests.
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
const context = require.context("./", true, /\.spec\.ts$/);
|
||||||
// And load the modules.
|
// And load the modules.
|
||||||
context.keys().map(context);
|
context.keys().map(context);
|
||||||
|
14
tslint.json
14
tslint.json
@ -56,10 +56,10 @@
|
|||||||
],
|
],
|
||||||
"object-literal-sort-keys": false,
|
"object-literal-sort-keys": false,
|
||||||
"ordered-imports": false,
|
"ordered-imports": false,
|
||||||
"quotemark": [
|
"quotemark": {
|
||||||
true,
|
"options": "double",
|
||||||
"single"
|
"severity": "warning"
|
||||||
],
|
},
|
||||||
"trailing-comma": false,
|
"trailing-comma": false,
|
||||||
"no-output-on-prefix": true,
|
"no-output-on-prefix": true,
|
||||||
"use-input-property-decorator": true,
|
"use-input-property-decorator": true,
|
||||||
@ -70,6 +70,10 @@
|
|||||||
"use-life-cycle-interface": true,
|
"use-life-cycle-interface": true,
|
||||||
"use-pipe-transform-interface": true,
|
"use-pipe-transform-interface": true,
|
||||||
"component-class-suffix": true,
|
"component-class-suffix": true,
|
||||||
"directive-class-suffix": true
|
"directive-class-suffix": true,
|
||||||
|
"indent": {
|
||||||
|
"options": "tabs",
|
||||||
|
"severity": "warning"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user