Explorar el Código

Umbau Tabelle. automatische Berechnung

Leonard Schulz (Arbeit) hace 2 años
padre
commit
1f751e1882

+ 96 - 49
fontend_angular/wbs-rechner-angular/src/app/app.component.html

@@ -2,66 +2,113 @@
 
 <app-headerbox [title]="'Haushaltsmitglieder'">
   <div toolbar>
-    <button
+    <a
       class="plus-button button"
       title="Person hinzufügen"
       (click)="addPerson()"
     >
       +
-    </button>
+  </a>
   </div>
   <div content>
-    <div class="table">
-      <div class="table-header mobile-not-visble">
-        <div class="table-cell">Nr.</div>
-        <div class="table-cell">Kindsalter</div>
-        <div class="table-cell">Freibeträge</div>
-        <div class="table-cell">Gesamteinkommen</div>
-        <div class="table-cell">Löschen</div>
-      </div>
-      <div class="table-body">
-        <div class="table-row" *ngFor="let person of persons">
-          <div class="table-header-mobile table-cell">
-            {{ person.index }}. Person
-            <button
-              class="delete-button button desktop-not-visble"
-              title="Person löschen"
-              (click)="deletePerson(person.index)"
-            >
-              &times;
-            </button>
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Kindsalter</span
-            >{{ person.index }}
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Freibeträge</span
-            >{{ person.index }}
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Gesamteinkommen</span
-            >{{ calculateTotalIncome(person) }}
-          </div>
-          <div class="table-cell mobile-not-visble">
-            <button
-              class="delete-button button"
-              title="Person löschen"
-              (click)="deletePerson(person.index)"
-            >
-              &times;
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
+    <table class="responsive-table">
+      <thead>
+        <tr>
+          <th>Nr.</th>
+          <th>Kindsalter</th>
+          <th>Freibeträge</th>
+          <th>Gesamteinkommen</th>
+          <th>Löschen</th>
+        </tr>
+      </thead>
+      <tbody>
+        <ng-container *ngFor="let person of persons">
+          <tr>
+            <td data-title="Nr.">
+              {{ person.index }}
+            </td>
+            <td data-title="Kindsalter">
+             {{ person.index }}
+            </td>
+            <td data-title="Freibeträge">
+             {{ person.index }}
+            </td>
+            <td data-title="Gesamteinkommen">
+              {{ person.totalincome }}
+            </td>
+            <td data-title="Löschen">
+              <a
+                class="delete-button button"
+                title="Person löschen"
+                (click)="deletePerson(person.index)"
+              >
+                &times;
+            </a>
+            </td>
+          </tr>
+        </ng-container>
+      </tbody>
+    </table>
 
   </div>
 </app-headerbox>
 
 
-<div *ngFor="let p of persons" style="margin-top: 20px;">
-    <app-income [person]="p">
+<div *ngFor="let person of persons" style="margin-top: 20px;">
+  <app-headerbox [title]="'Einkommen der ' + person.index + '. Person'">
+    <div toolbar>
+      <a class="plus-button button" title="Einkommen hinzufügen" (click)="addIncome(person.index)">
+        +
+      </a>
+    </div>
+    <div content>
+    <table class="responsive-table">
+      <thead>
+        <tr>
+          <th >Nr.</th>
+          <th >Typ</th>
+          <th>Frequenz</th>
+          <th >Brutto Betrag</th>
+          <th >jährliche Werbungskosten</th>
+          <th >Löschen</th>
+        </tr>
+      </thead>
+      <tbody>
+        <ng-container *ngFor="let income of person.incomes; let i = index">
+          <tr>
+            <td data-title="Nr.">
+              {{ income.index }}
+            </td>
+            <td data-title="Typ">
+              {{ income.type }}
+            </td>
+            <td data-title="Frequenz">
+            {{ income.frequency }}
+            </td>
+            <td data-title="Brutto Betrag">
+              <input type="number" [(ngModel)]="income.amount" (input)="calculateTotalIncome(person.index)">
+            </td>
+            <td data-title="jährliche Werbungskosten">
+              <input type="number" [(ngModel)]="income.advertisingCosts" (input)="calculateTotalIncome(person.index)">
+            </td>
+            <td data-title="Löschen">
+              <a class="delete-button button"
+                title="{{ income.index }}. Einkommen der {{person.index}}. Person löschen"
+                (click)="deleteIncome(person.index, income.index)">
+                &times;
+            </a>
+            </td>
+          </tr>
+        </ng-container>
+      </tbody>
+    </table>
+  
+  </div>
+  </app-headerbox>
+</div>
 
-    </app-income>
+<app-headerbox [title]="'WBS berechnen'">
+  <div content>
+    <button>WBS berechnen</button>
   </div>
+</app-headerbox>

+ 0 - 29
fontend_angular/wbs-rechner-angular/src/app/app.component.spec.ts

@@ -1,29 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-import { AppComponent } from './app.component';
-
-describe('AppComponent', () => {
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [AppComponent],
-    }).compileComponents();
-  });
-
-  it('should create the app', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app).toBeTruthy();
-  });
-
-  it(`should have the 'wbs-rechner-angular' title`, () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app.title).toEqual('wbs-rechner-angular');
-  });
-
-  it('should render title', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    fixture.detectChanges();
-    const compiled = fixture.nativeElement as HTMLElement;
-    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, wbs-rechner-angular');
-  });
-});

+ 27 - 10
fontend_angular/wbs-rechner-angular/src/app/app.component.ts

@@ -1,7 +1,6 @@
-import { Component } from '@angular/core';
-import { RouterOutlet } from '@angular/router';
+import { Component  } from '@angular/core';
+import { FormsModule } from '@angular/forms';
 import { HeaderboxComponent } from './headerbox/headerbox.component';
-import { IncomeComponent } from './income/income.component';
 import {NgFor} from '@angular/common';
 import { Income } from './incomes';
 import { Person } from './person';
@@ -10,28 +9,29 @@ import { Person } from './person';
 @Component({
   selector: 'app-root',
   standalone: true,
-  imports: [NgFor, RouterOutlet, HeaderboxComponent, IncomeComponent],
+  imports: [NgFor, HeaderboxComponent,FormsModule ],
   templateUrl: './app.component.html',
   styleUrl: './app.component.css'
 })
 
 export class AppComponent {
   title = 'wbs-rechner-angular';
-
+  
   persons: Array<Person> = [];
 
-  calculateTotalIncome(person: any): number {
+  calculateTotalIncome(personindex: number) {
     let totalIncome = 0;
-    for (const income of person.incomes) {
-      totalIncome += income.amount;
+    for (const income of this.persons[personindex-1].incomes) {
+      totalIncome += (income.amount - income.advertisingCosts);
     }
-    return totalIncome;
+    this.persons[personindex-1].totalincome = totalIncome;
   }
   
   addPerson() {
     const newPerson = {
       index: this.getHighestIndex(this.persons)+1,
-      incomes: []
+      incomes: [],
+      totalincome: 0
     };
     this.persons.push(newPerson);
   }
@@ -40,6 +40,23 @@ export class AppComponent {
     this.persons = this.persons.filter(person => person.index !== index);
   }
 
+  addIncome(index: number) {
+    const newincome = {
+      index: this.getHighestIndex(this.persons[index-1].incomes)+1,
+      amount: 0,
+      frequency: 0,
+      advertisingCosts: 0,
+      type: 0
+    };
+    this.persons[index-1].incomes.push(newincome);
+
+
+  }
+
+  deleteIncome(pindex: number, index: number) {
+    this.persons[index-1].incomes = this.persons[index-1].incomes.filter(income => income.index !== index);
+  }
+
   getHighestIndex(arr: any[]): number {
     let highestIndex = 0;
     for (const item of arr) {

+ 0 - 3
fontend_angular/wbs-rechner-angular/src/app/app.routes.ts

@@ -1,3 +0,0 @@
-import { Routes } from '@angular/router';
-
-export const routes: Routes = [];

+ 4 - 0
fontend_angular/wbs-rechner-angular/src/app/frequency.ts

@@ -0,0 +1,4 @@
+export interface Frequency {
+    value: number,
+    description: string
+}

+ 0 - 23
fontend_angular/wbs-rechner-angular/src/app/headerbox/headerbox.component.spec.ts

@@ -1,23 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { HeaderboxComponent } from './headerbox.component';
-
-describe('HeaderboxComponent', () => {
-  let component: HeaderboxComponent;
-  let fixture: ComponentFixture<HeaderboxComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [HeaderboxComponent]
-    })
-    .compileComponents();
-    
-    fixture = TestBed.createComponent(HeaderboxComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 0
fontend_angular/wbs-rechner-angular/src/app/income/income.component.css


+ 0 - 62
fontend_angular/wbs-rechner-angular/src/app/income/income.component.html

@@ -1,62 +0,0 @@
-<app-headerbox [title]="'Einkommen der ' + person.index + '. Person'">
-  <div toolbar>
-    <button
-      class="plus-button button"
-      title="Einkommen hinzufügen"
-      (click)="addIncome()"
-    >
-      +
-    </button>
-  </div>
-  <div content>
-    <div class="table">
-      <div class="table-header mobile-not-visble">
-        <div class="table-cell">Nr.</div>
-        <div class="table-cell">Typ</div>
-        <div class="table-cell">Frequenz</div>
-        <div class="table-cell">Brutto Betrag</div>
-        <div class="table-cell">jährliche Werbungskosten</div>
-        <div class="table-cell">Löschen</div>
-      </div>
-      <div class="table-body">
-        <div class="table-row" *ngFor="let income of person.incomes">
-          <div class="table-header-mobile table-cell">
-            {{ income.index }}. Einkommen
-            <button
-              class="delete-button button desktop-not-visble"
-              title="{{ income.index }}. Einkommen der {{person.index}}. Person löschen"
-              (click)="deleteIncome(income.index)"
-            >
-              &times;
-            </button>
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Typ</span>{{ income.type }}
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Frequenz</span
-            >{{ income.frequency }}
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile">Brutto Betrag</span
-            ><input type="number" [value]="income.amount">
-          </div>
-          <div class="table-cell">
-            <span class="table-cell-header-mobile"
-              >jährliche Werbungskosten</span
-            >{{ income.advertisingCosts }}
-          </div>
-          <div class="table-cell mobile-not-visble">
-            <button
-              class="delete-button button"
-              title="{{ income.index }}. Einkommen der {{person.index}}. Person löschen"
-              (click)="deleteIncome(income.index)"
-            >
-              &times;
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</app-headerbox>

+ 0 - 23
fontend_angular/wbs-rechner-angular/src/app/income/income.component.spec.ts

@@ -1,23 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { IncomeComponent } from './income.component';
-
-describe('IncomeComponent', () => {
-  let component: IncomeComponent;
-  let fixture: ComponentFixture<IncomeComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [IncomeComponent]
-    })
-    .compileComponents();
-    
-    fixture = TestBed.createComponent(IncomeComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 43
fontend_angular/wbs-rechner-angular/src/app/income/income.component.ts

@@ -1,43 +0,0 @@
-import { Component, Input  } from '@angular/core';
-import { HeaderboxComponent } from '../headerbox/headerbox.component';
-import {NgFor} from '@angular/common';
-import { Income } from '../incomes';
-import { Person } from '../person';
-
-@Component({
-  selector: 'app-income',
-  standalone: true,
-  imports: [HeaderboxComponent, NgFor],
-  templateUrl: './income.component.html',
-  styleUrl: './income.component.css'
-})
-
-export class IncomeComponent {
-  @Input() person: Person;
-
-  addIncome() {
-    const newincome = {
-      index: this.getHighestIndex(this.person.incomes)+1,
-      amount: 0,
-      frequency: 0,
-      advertisingCosts: 0,
-      type: 0
-    };
-    this.person.incomes.push(newincome);
-  }
-
-  deleteIncome(index: number) {
-    this.person.incomes = this.person.incomes.filter(income => income.index !== index);
-  }
-
-  getHighestIndex(arr: any[]): number {
-    let highestIndex = 0;
-    for (const item of arr) {
-      if (item.index > highestIndex) {
-        highestIndex = item.index;
-      }
-    }
-    return highestIndex;
-  }
-
-}

+ 1 - 0
fontend_angular/wbs-rechner-angular/src/app/person.ts

@@ -2,6 +2,7 @@ import { Income } from './incomes';
 
 export interface Person {
     index: number;
+    totalincome: number;
     incomes: Array<Income>;
 }
 

+ 68 - 69
fontend_angular/wbs-rechner-angular/src/styles.css

@@ -20,6 +20,12 @@ h2 {
   margin: 0px;
 }
 
+input {
+  border: 1px solid var(--highlight-color);;
+  font-size: 16px;
+
+}
+
 /* Checkbox Design */
 input[type="checkbox"] {
   width: 20px;
@@ -41,12 +47,12 @@ input[type="checkbox"]:checked {
 }
 
 .button {
-  font-size: 27px;
+
   font-weight: bolder;
   color: #333;
   cursor: pointer;
-  border: none;
-  background-color: transparent;
+ 
+ 
 }
 
 .plus-button:hover {
@@ -61,74 +67,67 @@ input[type="checkbox"]:checked {
   color: darkred;
 }
 
-/* Responsive Table Design */
-.table-header {
-  display: flex;
-  justify-content: space-between;
-  background-color: var(--light-highlight-color);
-  font-weight: bold;
-}
-.table-cell {
-  flex: 1;
-  padding: 5px;
-}
-.table-row {
-  display: flex;
-  border-top: 1px solid var(--light-highlight-color);
+.responsive-table {
+  width: 100%;
+  text-align: left;
+  border-collapse: collapse;
 }
-.table-row:first-child {
-  border-top: none;
-}
-.table-body {
-  display: flex;
-  flex-direction: column;
-}
-.table-row > .table-cell {
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-}
-.table-cell-header-mobile {
-  display: none;
-  width: 40%;
-  background-color: var(--light-highlight-color); 
-  padding: 5px;
-  font-weight: bold;
-  word-wrap: break-word; 
-  word-break: break-all; 
+.responsive-table thead tr { 
+  background-color: var(--light-highlight-color);
 }
 
-.desktop-not-visble {
-  display: none;
-}
+.responsive-table tr { border-top: 1px solid var(--highlight-color); }
+.responsive-table tr:first-child { border: none; }
 
-@media (max-width: 600px) {
-  .table-header-mobile {
-    padding: 5px !important;
-    background-color: var(--light-highlight-color); 
-    font-weight: bold;
-    word-wrap: break-word; 
-    word-break: break-all; 
-  }
-
-  .mobile-not-visble {
-    display: none !important;
-  }
-
-  .desktop-not-visble {
-    display: inline;
-  }
-
-  .table-cell-header-mobile {
-    display: block;
-  }
-
-  .table-row {
-    flex-direction: column;
-  }
-
-  .table-cell {
-    flex-basis: 100%;
-    padding: 0px;
-  } 
+/* Responsive Table Design */
+@media only screen and (max-width: 800px) {
+	
+	/* Force table to not be like tables anymore */
+	.responsive-table table, 
+	.responsive-table thead, 
+	.responsive-table tbody, 
+	.responsive-table th, 
+	.responsive-table td, 
+	.responsive-table tr { 
+		display: block; 
+	}
+ 
+	/* Hide table headers (but not display: none;, for accessibility) */
+	.responsive-table thead tr { 
+		position: absolute;
+		top: -9999px;
+		left: -9999px;
+	}
+
+  .responsive-table tr { border-top: 2px solid var(--highlight-color); }
+ 
+	.responsive-table td { 
+		/* Behave  like a "row" */
+		border: none;
+		position: relative;
+		white-space: normal;
+		text-align:left;
+
+		padding-left: 50% !important; 
+    
+	}
+  .responsive-table tr:first-child { border: none; }
+ 
+	.responsive-table td:before { 
+		position: absolute;
+		top: 0px;
+		left: 0px;
+    background-color: var(--light-highlight-color);
+    width: 50%;
+    height: 100%;
+		white-space: break-spaces;
+		font-weight: bold;
+
+	}
+
+  	/*
+	Label the data
+	*/
+	.responsive-table td:before { content: attr(data-title); }
 }
+