From c98819dea2eded5ddefa85751f564a46edcd25e7 Mon Sep 17 00:00:00 2001 From: mezhik91 Date: Sat, 5 Jun 2021 18:12:04 +0200 Subject: [PATCH 1/5] Initial state for Open-Closed --- src/app/app.component.ts | 24 +++++++++- src/app/app.module.ts | 16 ++++++- src/app/widget/widget.component.ts | 70 ++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 src/app/widget/widget.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 90abcad..d1a7bf5 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,7 +2,27 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-root', - template: ``, - styles: [], + template: ` + + My App + +
+ + +
+ `, + styles: [ + ` + .content { + background-color: #fff; + padding: 2rem; + height: calc(100vh - 64px); + display: flex; + box-sizing: border-box; + justify-content: center; + align-items: center; + } + `, + ], }) export class AppComponent {} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4b519a0..923ca97 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,10 +3,22 @@ import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { WidgetComponent } from './widget/widget.component'; @NgModule({ - declarations: [AppComponent], - imports: [BrowserModule, BrowserAnimationsModule], + declarations: [AppComponent, WidgetComponent], + imports: [ + BrowserModule, + BrowserAnimationsModule, + MatToolbarModule, + MatButtonModule, + MatDividerModule, + MatIconModule, + ], providers: [], bootstrap: [AppComponent], }) diff --git a/src/app/widget/widget.component.ts b/src/app/widget/widget.component.ts new file mode 100644 index 0000000..0642415 --- /dev/null +++ b/src/app/widget/widget.component.ts @@ -0,0 +1,70 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-widget', + template: ` +
+

Weather

+ +
+ + +
Currently
+
+ wb_sunny +
+25
+
+
+ +
Last sprint
+
+ assessment +
Planned: 25
+
Achieved: 20
+
+
+ `, + styles: [ + ` + :host { + display: block; + border: #f0ebeb solid 1px; + border-radius: 5px; + padding: 15px; + background-color: #fafafa; + width: 400px; + margin-left: 20px; + } + .wether-widget { + display: block; + text-align: center; + position: relative; + min-width: 190px; + } + .header { + display: flex; + align-items: center; + justify-content: space-between; + } + .widget-icon { + font-size: 64px; + width: 64px; + height: 64px; + color: orange; + } + .value { + font-size: 24px; + opacity: 0.7; + } + `, + ], +}) +export class WidgetComponent { + @Input() + widget: 'wether' | 'velocity' = 'wether'; + onExportJson() { + console.log('Export Json logic..'); + } +} From 227feb01cca1b824746e49b355d8c60e4344158d Mon Sep 17 00:00:00 2001 From: mezhik91 Date: Sat, 5 Jun 2021 18:35:43 +0200 Subject: [PATCH 2/5] Precondition for Barbara liskov principle --- src/app/app.component.ts | 11 ++++-- src/app/app.module.ts | 9 ++++- src/app/widget/velocity-content.component.ts | 15 ++++++++ src/app/widget/wether-content.component.ts | 14 ++++++++ src/app/widget/widget-content.scss | 17 +++++++++ src/app/widget/widget.component.ts | 36 ++------------------ 6 files changed, 66 insertions(+), 36 deletions(-) create mode 100644 src/app/widget/velocity-content.component.ts create mode 100644 src/app/widget/wether-content.component.ts create mode 100644 src/app/widget/widget-content.scss diff --git a/src/app/app.component.ts b/src/app/app.component.ts index d1a7bf5..62fe3fd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,8 +7,15 @@ import { Component } from '@angular/core'; My App
- - + + + + + + + +

Any content

+
`, styles: [ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 923ca97..966d0bf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,9 +8,16 @@ import { MatButtonModule } from '@angular/material/button'; import { MatDividerModule } from '@angular/material/divider'; import { MatIconModule } from '@angular/material/icon'; import { WidgetComponent } from './widget/widget.component'; +import { WetherContentComponent } from './widget/wether-content.component'; +import { VelocityContentComponent } from './widget/velocity-content.component'; @NgModule({ - declarations: [AppComponent, WidgetComponent], + declarations: [ + AppComponent, + WidgetComponent, + WetherContentComponent, + VelocityContentComponent, + ], imports: [ BrowserModule, BrowserAnimationsModule, diff --git a/src/app/widget/velocity-content.component.ts b/src/app/widget/velocity-content.component.ts new file mode 100644 index 0000000..ec709c0 --- /dev/null +++ b/src/app/widget/velocity-content.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-velocity-content', + template: ` +
Last sprint
+
+ assessment +
Planned: 25
+
Achieved: 20
+
+ `, + styleUrls: ['./widget-content.scss'], +}) +export class VelocityContentComponent {} diff --git a/src/app/widget/wether-content.component.ts b/src/app/widget/wether-content.component.ts new file mode 100644 index 0000000..7b18e87 --- /dev/null +++ b/src/app/widget/wether-content.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-wether-content', + template: ` +
Currently
+
+ wb_sunny +
+25
+
+ `, + styleUrls: ['./widget-content.scss'], +}) +export class WetherContentComponent {} diff --git a/src/app/widget/widget-content.scss b/src/app/widget/widget-content.scss new file mode 100644 index 0000000..a4cb196 --- /dev/null +++ b/src/app/widget/widget-content.scss @@ -0,0 +1,17 @@ +:host { + display: block; + text-align: center; + position: relative; + min-width: 190px; +} + +.widget-icon { + font-size: 64px; + width: 64px; + height: 64px; + color: orange; +} +.value { + font-size: 24px; + opacity: 0.7; +} diff --git a/src/app/widget/widget.component.ts b/src/app/widget/widget.component.ts index 0642415..7bf34c3 100644 --- a/src/app/widget/widget.component.ts +++ b/src/app/widget/widget.component.ts @@ -4,27 +4,13 @@ import { Component, Input } from '@angular/core'; selector: 'app-widget', template: `
-

Weather

+

{{ title }}

- -
Currently
-
- wb_sunny -
+25
-
-
- -
Last sprint
-
- assessment -
Planned: 25
-
Achieved: 20
-
-
+ `, styles: [ ` @@ -37,33 +23,17 @@ import { Component, Input } from '@angular/core'; width: 400px; margin-left: 20px; } - .wether-widget { - display: block; - text-align: center; - position: relative; - min-width: 190px; - } .header { display: flex; align-items: center; justify-content: space-between; } - .widget-icon { - font-size: 64px; - width: 64px; - height: 64px; - color: orange; - } - .value { - font-size: 24px; - opacity: 0.7; - } `, ], }) export class WidgetComponent { @Input() - widget: 'wether' | 'velocity' = 'wether'; + title: string = ''; onExportJson() { console.log('Export Json logic..'); } From 1415e3e39cef9d8f06cac2a1e49fc510da75a50f Mon Sep 17 00:00:00 2001 From: mezhik91 Date: Sat, 5 Jun 2021 18:48:32 +0200 Subject: [PATCH 3/5] Precondition for interface segregation --- src/app/widget/widget-base.ts | 10 ++++++++++ src/app/widget/widget.component.ts | 11 +++-------- 2 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 src/app/widget/widget-base.ts diff --git a/src/app/widget/widget-base.ts b/src/app/widget/widget-base.ts new file mode 100644 index 0000000..4216677 --- /dev/null +++ b/src/app/widget/widget-base.ts @@ -0,0 +1,10 @@ +import { Directive, Input } from '@angular/core'; + +@Directive() +export class WidgetBase { + @Input() + title: string = ''; + onExportJson() { + console.log('Export Json logic..'); + } +} diff --git a/src/app/widget/widget.component.ts b/src/app/widget/widget.component.ts index 7bf34c3..460e3f1 100644 --- a/src/app/widget/widget.component.ts +++ b/src/app/widget/widget.component.ts @@ -1,4 +1,5 @@ -import { Component, Input } from '@angular/core'; +import { WidgetBase } from './widget-base'; +import { Component } from '@angular/core'; @Component({ selector: 'app-widget', @@ -31,10 +32,4 @@ import { Component, Input } from '@angular/core'; `, ], }) -export class WidgetComponent { - @Input() - title: string = ''; - onExportJson() { - console.log('Export Json logic..'); - } -} +export class WidgetComponent extends WidgetBase {} From b5be51c8f6510751446fae4845298969704b9edf Mon Sep 17 00:00:00 2001 From: mezhik91 Date: Sat, 5 Jun 2021 19:09:57 +0200 Subject: [PATCH 4/5] initial state for Dependency inversion principle --- src/app/widget/velocity-content.component.ts | 5 ++++- src/app/widget/wether-content.component.ts | 9 ++++++++- src/app/widget/widget-content.ts | 8 ++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/app/widget/widget-content.ts diff --git a/src/app/widget/velocity-content.component.ts b/src/app/widget/velocity-content.component.ts index ec709c0..c58649f 100644 --- a/src/app/widget/velocity-content.component.ts +++ b/src/app/widget/velocity-content.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { WidgetContent } from './widget-content'; @Component({ selector: 'app-velocity-content', @@ -12,4 +13,6 @@ import { Component } from '@angular/core'; `, styleUrls: ['./widget-content.scss'], }) -export class VelocityContentComponent {} +export class VelocityContentComponent implements WidgetContent { + id = 'random-string'; +} diff --git a/src/app/widget/wether-content.component.ts b/src/app/widget/wether-content.component.ts index 7b18e87..744871f 100644 --- a/src/app/widget/wether-content.component.ts +++ b/src/app/widget/wether-content.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { WidgetContent, Reloadable } from './widget-content'; @Component({ selector: 'app-wether-content', @@ -11,4 +12,10 @@ import { Component } from '@angular/core'; `, styleUrls: ['./widget-content.scss'], }) -export class WetherContentComponent {} +export class WetherContentComponent implements WidgetContent, Reloadable { + id = 'random-string'; + isLoading = false; + reload() { + console.log('...reloading is happening...'); + } +} diff --git a/src/app/widget/widget-content.ts b/src/app/widget/widget-content.ts new file mode 100644 index 0000000..df4b5e0 --- /dev/null +++ b/src/app/widget/widget-content.ts @@ -0,0 +1,8 @@ +export interface WidgetContent { + id: string; +} + +export interface Reloadable { + reload: () => any; + isLoading: boolean; +} From 7d854a955ba582e775d0117219d9670b533e684e Mon Sep 17 00:00:00 2001 From: mezhik91 Date: Mon, 7 Jun 2021 12:21:58 +0200 Subject: [PATCH 5/5] Dependency inversion principle implementation --- src/app/widget/wether-content.component.ts | 4 ++++ src/app/widget/widget-content.token.ts | 5 +++++ src/app/widget/widget.component.ts | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 src/app/widget/widget-content.token.ts diff --git a/src/app/widget/wether-content.component.ts b/src/app/widget/wether-content.component.ts index 744871f..d7c6494 100644 --- a/src/app/widget/wether-content.component.ts +++ b/src/app/widget/wether-content.component.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; import { WidgetContent, Reloadable } from './widget-content'; +import { RELOADABLE_CONTENT } from './widget-content.token'; @Component({ selector: 'app-wether-content', @@ -11,6 +12,9 @@ import { WidgetContent, Reloadable } from './widget-content'; `, styleUrls: ['./widget-content.scss'], + providers: [ + { provide: RELOADABLE_CONTENT, useExisting: WetherContentComponent }, + ], }) export class WetherContentComponent implements WidgetContent, Reloadable { id = 'random-string'; diff --git a/src/app/widget/widget-content.token.ts b/src/app/widget/widget-content.token.ts new file mode 100644 index 0000000..c6ed62e --- /dev/null +++ b/src/app/widget/widget-content.token.ts @@ -0,0 +1,5 @@ +import { Reloadable } from './widget-content'; +import { InjectionToken } from '@angular/core'; +export const RELOADABLE_CONTENT = new InjectionToken( + 'reloadable-content' +); diff --git a/src/app/widget/widget.component.ts b/src/app/widget/widget.component.ts index 460e3f1..ef8390f 100644 --- a/src/app/widget/widget.component.ts +++ b/src/app/widget/widget.component.ts @@ -1,5 +1,8 @@ +import { WetherContentComponent } from './wether-content.component'; import { WidgetBase } from './widget-base'; -import { Component } from '@angular/core'; +import { Component, ContentChild } from '@angular/core'; +import { RELOADABLE_CONTENT } from './widget-content.token'; +import { Reloadable } from './widget-content'; @Component({ selector: 'app-widget', @@ -32,4 +35,13 @@ import { Component } from '@angular/core'; `, ], }) -export class WidgetComponent extends WidgetBase {} +export class WidgetComponent extends WidgetBase { + @ContentChild(RELOADABLE_CONTENT) + content?: Reloadable; + + ngAfterContentInit(): void { + if (this.content) { + this.content.reload(); + } + } +}