Refactor input fields, converter selectors and error messages into their own components.
Some checks failed
continuous-integration/drone the build failed
Some checks failed
continuous-integration/drone the build failed
This commit is contained in:
parent
62ba5a3357
commit
81db470a5a
16 changed files with 337 additions and 157 deletions
|
@ -1,18 +1,7 @@
|
|||
<div *ngFor="let step of steps" class="inputwrapper">
|
||||
<div class="textwrapper arrow_box">
|
||||
<textarea class="textinput" (keyup)="update(step)" placeholder="Please enter your input ..."
|
||||
[(ngModel)]="step.content">{{step.content}}</textarea>
|
||||
</div>
|
||||
<div [ngClass]="{selectwrapper: true, error: step.error}">
|
||||
<div class="arrow_box">
|
||||
<select class="select" (change)="convert(step, $event)">
|
||||
<option id="undefined">Select conversion ...</option>
|
||||
<option class="option" *ngFor="let c of converters" id="{{c.getId()}}">{{c.getDisplayname()}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="errormessage" *ngIf="step.error" [innerHTML]="step.message"></div>
|
||||
<app-text-input-field [step]="step" #ti></app-text-input-field>
|
||||
<app-converter-selector [step]="step" [textInput]="ti"></app-converter-selector>
|
||||
<app-error-message [step]="step"></app-error-message>
|
||||
</div>
|
||||
<app-version></app-version>
|
||||
<!--<router-outlet></router-outlet>-->
|
||||
|
|
|
@ -2,106 +2,3 @@
|
|||
font-family: "ABeeZee", sans-serif;
|
||||
margin: 0 1em 1em 1em;
|
||||
}
|
||||
|
||||
.textwrapper {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0 1em 0 0;
|
||||
}
|
||||
|
||||
.arrow_box {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border: 1px solid #aaa;
|
||||
&:focus {
|
||||
border-color: #888;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #333;
|
||||
}
|
||||
&:after, &:before {
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
&:after {
|
||||
border-color: rgba(255, 255, 255, 0);
|
||||
border-top-color: #fff;
|
||||
border-width: 1em;
|
||||
margin-left: -1em;
|
||||
}
|
||||
&:before {
|
||||
border-color: rgba(170, 170, 170, 0);
|
||||
border-top-color: #aaa;
|
||||
border-width: calc(1em + 1px);
|
||||
margin-left: calc(-1em - 1px);
|
||||
}
|
||||
&:focus:before {
|
||||
border-color: rgba(136, 136, 136, 0);
|
||||
border-top-color: #888;
|
||||
}
|
||||
&:hover:before {
|
||||
border-color: rgba(51, 51, 51, 0);
|
||||
border-top-color: #333;
|
||||
}
|
||||
.selectwrapper > & {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.textinput {
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
color: #000;
|
||||
font-family: "Free Monospaced", monospace;
|
||||
height: 10em;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
&:focus {
|
||||
border-color: #888;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.selectwrapper {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
&.error {
|
||||
> .arrow_box {
|
||||
border-color: red;
|
||||
&:before {
|
||||
border-top-color: red;
|
||||
}
|
||||
}
|
||||
select {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
color: #000;
|
||||
font-family: "ABeeZee", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.option {
|
||||
/* font-family: "ABeeZee", sans-serif;*/
|
||||
}
|
||||
|
||||
.errormessage {
|
||||
color: red;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {ConverterRegistryService} from './converter-registry.service';
|
||||
import {InputComponentManagerService} from './input-component-manager.service';
|
||||
import {Step} from './step';
|
||||
import {Converter} from './converter/converter';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -11,47 +9,11 @@ import {Converter} from './converter/converter';
|
|||
})
|
||||
export class AppComponent implements OnInit {
|
||||
public steps: Step[] = [];
|
||||
public converters: Converter[] = [];
|
||||
|
||||
constructor(private converterRegistryService: ConverterRegistryService,
|
||||
private inputComponentManagerService: InputComponentManagerService) {
|
||||
}
|
||||
|
||||
convert(step: Step, $event: any): void {
|
||||
step.selectedConverter = this.converterRegistryService.getConverter($event.target.selectedOptions[0].id);
|
||||
this.update(step);
|
||||
}
|
||||
|
||||
update(step: Step): void {
|
||||
const converter: Converter = step.selectedConverter;
|
||||
|
||||
if (converter !== undefined) {
|
||||
const content: string = step.content;
|
||||
let result: string;
|
||||
try {
|
||||
result = converter.convert(content);
|
||||
} catch (error) {
|
||||
if (typeof console === 'object' && typeof console.log === 'function') {
|
||||
console.log(error);
|
||||
}
|
||||
step.message = error.message;
|
||||
step.error = true;
|
||||
result = null;
|
||||
}
|
||||
if (result !== null) {
|
||||
step.message = '';
|
||||
step.error = false;
|
||||
if (result !== '') {
|
||||
const nextComponent: Step = this.inputComponentManagerService.getNext(step);
|
||||
nextComponent.content = result;
|
||||
this.update(nextComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
constructor(private inputComponentManagerService: InputComponentManagerService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.converters = this.converterRegistryService.getAllConverters();
|
||||
this.steps = this.inputComponentManagerService.getAllComponents();
|
||||
this.inputComponentManagerService.getFirst();
|
||||
}
|
||||
|
|
|
@ -6,11 +6,17 @@ import {InputComponentManagerService} from './input-component-manager.service';
|
|||
import {NativeLibraryWrapperService} from './native-library-wrapper.service';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {VersionComponent} from './version/version.component';
|
||||
import { TextInputFieldComponent } from './text-input-field/text-input-field.component';
|
||||
import { ConverterSelectorComponent } from './converter-selector/converter-selector.component';
|
||||
import { ErrorMessageComponent } from './error-message/error-message.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
VersionComponent
|
||||
VersionComponent,
|
||||
TextInputFieldComponent,
|
||||
ConverterSelectorComponent,
|
||||
ErrorMessageComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<div [ngClass]="{selectwrapper: true, error: step.error}">
|
||||
<div class="arrow_box">
|
||||
<select class="select" (change)="convert(step, $event)">
|
||||
<option id="undefined">Select conversion ...</option>
|
||||
<option class="option" *ngFor="let c of converters" id="{{c.getId()}}">{{c.getDisplayname()}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
74
src/app/converter-selector/converter-selector.component.scss
Normal file
74
src/app/converter-selector/converter-selector.component.scss
Normal file
|
@ -0,0 +1,74 @@
|
|||
.selectwrapper {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
&.error {
|
||||
> .arrow_box {
|
||||
border-color: red;
|
||||
&:before {
|
||||
border-top-color: red;
|
||||
}
|
||||
}
|
||||
select {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
color: #000;
|
||||
font-family: "ABeeZee", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.arrow_box {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border: 1px solid #aaa;
|
||||
&:focus {
|
||||
border-color: #888;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #333;
|
||||
}
|
||||
&:after, &:before {
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
&:after {
|
||||
border-color: rgba(255, 255, 255, 0);
|
||||
border-top-color: #fff;
|
||||
border-width: 1em;
|
||||
margin-left: -1em;
|
||||
}
|
||||
&:before {
|
||||
border-color: rgba(170, 170, 170, 0);
|
||||
border-top-color: #aaa;
|
||||
border-width: calc(1em + 1px);
|
||||
margin-left: calc(-1em - 1px);
|
||||
}
|
||||
&:focus:before {
|
||||
border-color: rgba(136, 136, 136, 0);
|
||||
border-top-color: #888;
|
||||
}
|
||||
&:hover:before {
|
||||
border-color: rgba(51, 51, 51, 0);
|
||||
border-top-color: #333;
|
||||
}
|
||||
.selectwrapper > & {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.option {
|
||||
/* font-family: "ABeeZee", sans-serif;*/
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ConverterSelectorComponent } from './converter-selector.component';
|
||||
|
||||
describe('ConverterSelectorComponent', () => {
|
||||
let component: ConverterSelectorComponent;
|
||||
let fixture: ComponentFixture<ConverterSelectorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConverterSelectorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConverterSelectorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
30
src/app/converter-selector/converter-selector.component.ts
Normal file
30
src/app/converter-selector/converter-selector.component.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {Step} from '../step';
|
||||
import {Converter} from '../converter/converter';
|
||||
import {ConverterRegistryService} from '../converter-registry.service';
|
||||
import {TextInputFieldComponent} from '../text-input-field/text-input-field.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-converter-selector',
|
||||
templateUrl: './converter-selector.component.html',
|
||||
styleUrls: ['./converter-selector.component.scss']
|
||||
})
|
||||
export class ConverterSelectorComponent implements OnInit {
|
||||
@Input()
|
||||
public step: Step;
|
||||
@Input()
|
||||
private textInput: TextInputFieldComponent;
|
||||
public converters: Converter[] = [];
|
||||
|
||||
constructor(private converterRegistryService: ConverterRegistryService) {
|
||||
}
|
||||
|
||||
convert(step: Step, $event: any): void {
|
||||
step.selectedConverter = this.converterRegistryService.getConverter($event.target.selectedOptions[0].id);
|
||||
this.textInput.update(step);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.converters = this.converterRegistryService.getAllConverters();
|
||||
}
|
||||
}
|
1
src/app/error-message/error-message.component.html
Normal file
1
src/app/error-message/error-message.component.html
Normal file
|
@ -0,0 +1 @@
|
|||
<div class="errormessage" *ngIf="step.error" [innerHTML]="step.message"></div>
|
4
src/app/error-message/error-message.component.scss
Normal file
4
src/app/error-message/error-message.component.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
.errormessage {
|
||||
color: red;
|
||||
text-align: center;
|
||||
}
|
25
src/app/error-message/error-message.component.spec.ts
Normal file
25
src/app/error-message/error-message.component.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ErrorMessageComponent } from './error-message.component';
|
||||
|
||||
describe('ErrorMessageComponent', () => {
|
||||
let component: ErrorMessageComponent;
|
||||
let fixture: ComponentFixture<ErrorMessageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ErrorMessageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ErrorMessageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/error-message/error-message.component.ts
Normal file
15
src/app/error-message/error-message.component.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {Component, Input} from '@angular/core';
|
||||
import {Step} from '../step';
|
||||
|
||||
@Component({
|
||||
selector: 'app-error-message',
|
||||
templateUrl: './error-message.component.html',
|
||||
styleUrls: ['./error-message.component.scss']
|
||||
})
|
||||
export class ErrorMessageComponent {
|
||||
@Input()
|
||||
public step: Step;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
}
|
4
src/app/text-input-field/text-input-field.component.html
Normal file
4
src/app/text-input-field/text-input-field.component.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<div class="textwrapper arrow_box">
|
||||
<textarea class="textinput" (keyup)="update(step)" placeholder="Please enter your input ..."
|
||||
[(ngModel)]="step.content">{{step.content}}</textarea>
|
||||
</div>
|
69
src/app/text-input-field/text-input-field.component.scss
Normal file
69
src/app/text-input-field/text-input-field.component.scss
Normal file
|
@ -0,0 +1,69 @@
|
|||
.textwrapper {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0 1em 0 0;
|
||||
}
|
||||
|
||||
.arrow_box {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border: 1px solid #aaa;
|
||||
&:focus {
|
||||
border-color: #888;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #333;
|
||||
}
|
||||
&:after, &:before {
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
&:after {
|
||||
border-color: rgba(255, 255, 255, 0);
|
||||
border-top-color: #fff;
|
||||
border-width: 1em;
|
||||
margin-left: -1em;
|
||||
}
|
||||
&:before {
|
||||
border-color: rgba(170, 170, 170, 0);
|
||||
border-top-color: #aaa;
|
||||
border-width: calc(1em + 1px);
|
||||
margin-left: calc(-1em - 1px);
|
||||
}
|
||||
&:focus:before {
|
||||
border-color: rgba(136, 136, 136, 0);
|
||||
border-top-color: #888;
|
||||
}
|
||||
&:hover:before {
|
||||
border-color: rgba(51, 51, 51, 0);
|
||||
border-top-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.textinput {
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
color: #000;
|
||||
font-family: "Free Monospaced", monospace;
|
||||
height: 10em;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
&:focus {
|
||||
border-color: #888;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.errormessage {
|
||||
color: red;
|
||||
text-align: center;
|
||||
}
|
25
src/app/text-input-field/text-input-field.component.spec.ts
Normal file
25
src/app/text-input-field/text-input-field.component.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TextInputFieldComponent } from './text-input-field.component';
|
||||
|
||||
describe('TextInputFieldComponent', () => {
|
||||
let component: TextInputFieldComponent;
|
||||
let fixture: ComponentFixture<TextInputFieldComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ TextInputFieldComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TextInputFieldComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
45
src/app/text-input-field/text-input-field.component.ts
Normal file
45
src/app/text-input-field/text-input-field.component.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import {Component, Input} from '@angular/core';
|
||||
import {Step} from '../step';
|
||||
import {Converter} from '../converter/converter';
|
||||
import {InputComponentManagerService} from '../input-component-manager.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-text-input-field',
|
||||
templateUrl: './text-input-field.component.html',
|
||||
styleUrls: ['./text-input-field.component.scss']
|
||||
})
|
||||
export class TextInputFieldComponent {
|
||||
@Input()
|
||||
public step: Step;
|
||||
|
||||
constructor(private inputComponentManagerService: InputComponentManagerService) {
|
||||
}
|
||||
|
||||
update(step: Step): void {
|
||||
const converter: Converter = step.selectedConverter;
|
||||
|
||||
if (converter !== undefined) {
|
||||
const content: string = step.content;
|
||||
let result: string;
|
||||
try {
|
||||
result = converter.convert(content);
|
||||
} catch (error) {
|
||||
if (typeof console === 'object' && typeof console.log === 'function') {
|
||||
console.log(error);
|
||||
}
|
||||
step.message = error.message;
|
||||
step.error = true;
|
||||
result = null;
|
||||
}
|
||||
if (result !== null) {
|
||||
step.message = '';
|
||||
step.error = false;
|
||||
if (result !== '') {
|
||||
const nextComponent: Step = this.inputComponentManagerService.getNext(step);
|
||||
nextComponent.content = result;
|
||||
this.update(nextComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue