diff --git a/src/angular/app/app.module.ts b/src/angular/app/app.module.ts
index 2c3ba29..4572b5f 100644
--- a/src/angular/app/app.module.ts
+++ b/src/angular/app/app.module.ts
@@ -1,18 +1,20 @@
-import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
-
+import { ReactiveFormsModule } from '@angular/forms';
+import { BrowserModule } from '@angular/platform-browser';
+import { RouterModule } from '@angular/router';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { MutiplesComponent } from './components/mutiples/mutiples.component';
@NgModule({
- declarations: [
- AppComponent
- ],
+ declarations: [AppComponent, MutiplesComponent],
imports: [
BrowserModule,
- AppRoutingModule
+ AppRoutingModule,
+ ReactiveFormsModule,
+ RouterModule.forRoot([{ path: '', component: MutiplesComponent }]),
],
providers: [],
- bootstrap: [AppComponent]
+ bootstrap: [AppComponent],
})
-export class AppModule { }
+export class AppModule {}
diff --git a/src/angular/app/components/mutiples/mutiples.component.html b/src/angular/app/components/mutiples/mutiples.component.html
new file mode 100644
index 0000000..c2a7dbf
--- /dev/null
+++ b/src/angular/app/components/mutiples/mutiples.component.html
@@ -0,0 +1,26 @@
+
+
+
Times table
+
+
+
+ {{ timesTableForm.value.input }} * {{ 1 + i }} = {{ multiple }}
+
+
+
diff --git a/src/angular/app/components/mutiples/mutiples.component.scss b/src/angular/app/components/mutiples/mutiples.component.scss
new file mode 100644
index 0000000..6881cfd
--- /dev/null
+++ b/src/angular/app/components/mutiples/mutiples.component.scss
@@ -0,0 +1,23 @@
+#multiples {
+ position: absolute;
+ left: 0;
+ top: 210px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ color: #ffffff;
+ font-weight: 900;
+
+ .container {
+ background-color: #d47800e0;
+ border-radius: 4px;
+ padding: 20px;
+
+ form {
+ display: flex;
+ > * {
+ margin: 5px;
+ }
+ }
+ }
+}
diff --git a/src/angular/app/components/mutiples/mutiples.component.spec.ts b/src/angular/app/components/mutiples/mutiples.component.spec.ts
new file mode 100644
index 0000000..a5b2e74
--- /dev/null
+++ b/src/angular/app/components/mutiples/mutiples.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MutiplesComponent } from './mutiples.component';
+
+describe('MutiplesComponent', () => {
+ let component: MutiplesComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ MutiplesComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MutiplesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/angular/app/components/mutiples/mutiples.component.ts b/src/angular/app/components/mutiples/mutiples.component.ts
new file mode 100644
index 0000000..351298f
--- /dev/null
+++ b/src/angular/app/components/mutiples/mutiples.component.ts
@@ -0,0 +1,40 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup } from '@angular/forms';
+import { ElectronIpcService } from 'angular/app/services/electron-ipc.service';
+import { WindowApiConst } from 'shared';
+
+@Component({
+ selector: 'app-mutiples',
+ templateUrl: './mutiples.component.html',
+ styleUrls: ['./mutiples.component.scss'],
+})
+export class MutiplesComponent implements OnInit {
+ timesTableForm = new FormGroup({
+ input: new FormControl(Math.round(Math.random() * 100) % 10),
+ });
+
+ multiples = [];
+
+ constructor(private electronIpc: ElectronIpcService) {}
+
+ ngOnInit(): void {
+ // Specifying what to do with received data from main process
+ this.electronIpc.receive(WindowApiConst.MULTIPLES_OUTPUT, (...data) => {
+ // Update current data
+ this.multiples = data;
+ });
+
+ // Reset multiples on form changes
+ this.timesTableForm.valueChanges.subscribe((value) => {
+ this.multiples = [];
+ });
+
+ // Init time tables with given random value
+ this.onSubmit();
+ }
+
+ onSubmit() {
+ const intput = this.timesTableForm.value.input;
+ this.electronIpc.send(WindowApiConst.MULTIPLES_INPUT, intput);
+ }
+}
diff --git a/src/angular/app/services/electron-ipc.service.spec.ts b/src/angular/app/services/electron-ipc.service.spec.ts
new file mode 100644
index 0000000..9470d3c
--- /dev/null
+++ b/src/angular/app/services/electron-ipc.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ElectronIpcService } from './electron-ipc.service';
+
+describe('ElectronIpcService', () => {
+ let service: ElectronIpcService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(ElectronIpcService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/angular/app/services/electron-ipc.service.ts b/src/angular/app/services/electron-ipc.service.ts
new file mode 100644
index 0000000..d1d6fc9
--- /dev/null
+++ b/src/angular/app/services/electron-ipc.service.ts
@@ -0,0 +1,44 @@
+import { Injectable, NgZone } from '@angular/core';
+import { WindowApi } from 'shared';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class ElectronIpcService {
+ private _api: WindowApi;
+
+ constructor(private zone: NgZone) {
+ if (window && (window as any).api) {
+ try {
+ this._api = (window as any).api;
+ } catch (e) {
+ throw e;
+ }
+ console.log('Preloader API has been loaded successfully');
+ } else {
+ console.warn('Preloader API is not loaded');
+ }
+ }
+
+ public receive(channel: string, func: (...data) => void): void {
+ if (this._api) {
+ this._api.receive(channel, (...data) => {
+ console.log(`Received from main process channel [${channel}]`, data);
+
+ // Next code might run outside of Angular zone and therefore Angular
+ // doesn't recognize it needs to run change detection
+ // Further details on SO : https://stackoverflow.com/a/49136353/11480016
+ this.zone.run(() => {
+ func(...data);
+ });
+ });
+ }
+ }
+
+ public send(channel: string, ...data): void {
+ if (this._api) {
+ console.log(`Sending to main process channel [${channel}]`, data);
+ this._api.send(channel, ...data);
+ }
+ }
+}