Переглянути джерело

all functions + restyling of notes function

Warafear 7 місяців тому
батько
коміт
fb03f00bfe

+ 1 - 1
src/app/character/character-creator/character-creator.component.ts

@@ -384,7 +384,7 @@ export class CharacterCreatorComponent {
       this.dataAccessor.addData(
         this.characterName,
         {
-          data: {},
+          data: [],
         },
         'notes',
       ),

+ 54 - 39
src/app/journal/journal-notes/journal-notes.component.html

@@ -1,28 +1,58 @@
-<div class="entries-container">
-  @for (entry of entries; let index = $index; track entry) {
-    <div
-      (click)="activateEntry(index)"
-      [ngClass]="currentEntryIndex === index ? 'active' : ''"
-      class="entry"
-    >
+<div class="entries-list">
+  <!-- Add Button or temporary unsaved new entry -->
+  @if (isNewEntry) {
+    <div class="entry active">
       <div class="entry-title">
-        @if (entries[index].title !== "") {
-          {{ entries[index].title }}
+        @if (currentEntry.title !== "") {
+          {{ currentEntry.title }}
         } @else {
-          Kein Titel
+          Noch kein Titel
         }
       </div>
       <div class="entry-date">
-        {{ entries[index].created | date: "shortDate" : "" : "de" }}
+        {{ currentEntry.created | date: "shortDate" : "" : "de" }}
+      </div>
+      <div class="unsaved">Nicht gespeichert</div>
+    </div>
+  } @else {
+    <div class="entry add-button" (click)="addEntry()">
+      <img src="assets/icons/UIIcons/add.svg" />
+    </div>
+  }
+  <!-- List of entries -->
+  @for (entry of entries; let index = $index; track entry) {
+    <div
+      class="entry-wrapper"
+      [ngClass]="{
+        active: currentEntryIndex === index,
+        'edit-mode': isInEditMode
+      }"
+    >
+      <div (click)="selectEntry(index)" class="entry">
+        <div class="entry-title">
+          @if (entries[index].title !== "") {
+            {{ entries[index].title }}
+          } @else {
+            Kein Titel
+          }
+        </div>
+        <div class="entry-date">
+          {{ entries[index].created | date: "shortDate" : "" : "de" }}
+        </div>
+        @if (isInEditMode && currentEntryIndex === index) {
+          <div class="unsaved">Nicht gespeichert</div>
+        }
+      </div>
+      <div class="control-button-wrapper">
+        <icon-button [icon]="'edit'" (click)="editEntry()"></icon-button>
+        <icon-button [icon]="'delete'" (click)="deleteEntry()"></icon-button>
       </div>
     </div>
   }
-  <div class="entry add-button" (click)="addEntry()">
-    <img src="assets/icons/UIIcons/add.svg" />
-  </div>
 </div>
 
-@if (currentEntryIndex !== -1) {
+<!-- Entry container, shows the currentEntry -->
+@if (currentEntryIndex !== -1 || isNewEntry) {
   <div class="entry-container">
     @if (isInEditMode) {
       <!-- Title -->
@@ -69,34 +99,19 @@
     }
     <div class="button-row">
       @if (isInEditMode) {
-        @if (isNewEntry) {
-          <ui-button width="w16" (click)="saveEntry()">Speichern</ui-button>
-          <ui-button width="w16" (click)="deleteEntry()">Löschen</ui-button>
-        } @else {
-          <ui-button width="w16" (click)="saveEntry()">Speichern</ui-button>
-          <ui-button width="w16" (click)="discardEntry()">Verwerfen</ui-button>
-        }
-      } @else {
-        <ui-button width="w16" (click)="isInEditMode = true"
-          >Bearbeiten</ui-button
-        >
+        <ui-button width="w16" (click)="saveEntry()">Speichern</ui-button>
+        <ui-button width="w16" (click)="discardEntry()">Verwerfen</ui-button>
+      }
+      <!-- @else {
+        <ui-button width="w16" (click)="editEntry()">Bearbeiten</ui-button>
         <ui-button width="w16" (click)="deleteEntry()"
           >Eintrag löschen</ui-button
         >
-      }
-
-      <!-- <ui-button width="w16" (click)="isInEditMode = false"
-        >Zur Leseansicht</ui-button
-      >
-    } @else {
-      <ui-button width="w16" (click)="isInEditMode = true"
-        >Bearbeiten</ui-button
-      >
-    } -->
-      <!-- <ui-button style="width: 10rem" (click)="discardChanges()">Verwerfen</ui-button>
-    <ui-button style="width: 10rem" (click)="editEntry()">Bearbeiten</ui-button> -->
+      } -->
     </div>
   </div>
 } @else {
-  <div class="empty">Noch kein Eintrag vorhanden</div>
+  <div style="margin: 5rem auto; text-align: center">
+    Noch kein Eintrag vorhanden
+  </div>
 }

+ 49 - 17
src/app/journal/journal-notes/journal-notes.component.scss

@@ -1,10 +1,13 @@
-.entries-container {
+.entries-list {
   width: 18rem;
   height: 100%;
   overflow-y: auto;
   position: fixed;
   top: 0;
   left: 0;
+  display: flex;
+  flex-direction: column;
+  gap: 1rem;
   background-image: url("../../../assets/images/texture-10.jpg");
   border-right: var(--gold-3);
   box-shadow: var(--shadow);
@@ -12,37 +15,70 @@
 
   .entry {
     width: 15rem;
-    margin: 0 auto 1rem;
+    margin-left: 1rem;
     padding: 1rem;
     border: var(--gold-2);
     border-radius: 10px;
+    box-shadow: var(--shadow);
+    cursor: pointer;
     background-image: url("../../../assets/images/texture-0.jpg");
     &:hover {
       background-image: url("../../../assets/images/texture-5.jpg");
     }
+    .entry-title {
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    .entry-date {
+    }
+
+    .unsaved {
+      color: rgb(46, 35, 35);
+      font-size: 0.75rem;
+      font-weight: 600;
+    }
   }
 
-  .entry-title {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
+  .control-button-wrapper {
+    display: flex;
+    flex-direction: column;
+    gap: 0.75rem;
+    // justify-content: space-between;
   }
 
-  .entry-date {
+  .entry-wrapper {
+    display: flex;
+    align-items: center;
+    .control-button-wrapper {
+      display: none;
+    }
+
+    &.active:not(.edit-mode) {
+      .entry {
+        width: 13rem;
+        background-image: url("../../../assets/images/texture-30.jpg") !important;
+      }
+      .control-button-wrapper {
+        display: flex;
+      }
+    }
+    &.active {
+      .entry {
+        background-image: url("../../../assets/images/texture-30.jpg") !important;
+      }
+    }
   }
 
   .add-button {
+    height: 5rem;
     display: flex;
     justify-content: center;
     align-items: center;
   }
 }
 
-.active {
-  // border: var(--gold-3) !important;
-  background-image: url("../../../assets/images/texture-20.jpg") !important;
-}
-
 .entry-container {
   width: 800px;
   margin-left: calc(50vw - 400px + 9rem);
@@ -87,10 +123,6 @@
     border-radius: 0 0 4px 4px;
   }
 
-  // .NgxEditor__Content {
-  //   height: 30rem;
-  // }
-
   // READ VIEW
 
   .title-row {
@@ -130,7 +162,7 @@
 
   .read-container {
     margin-top: 1.5rem;
-    height: calc(100vh - 14.375rem);
+    height: calc(100vh - 10rem);
     padding: 2rem 2rem;
     overflow: auto;
     border-radius: 6px;

+ 72 - 31
src/app/journal/journal-notes/journal-notes.component.ts

@@ -4,6 +4,7 @@ import { DateAdapter } from '@angular/material/core';
 import { JournalEntry } from 'src/interfaces/interfaces';
 import localeDe from '@angular/common/locales/de';
 import { registerLocaleData } from '@angular/common';
+import { DataService } from 'src/services/data/data.service';
 
 @Component({
   selector: 'app-journal-notes',
@@ -12,25 +13,6 @@ import { registerLocaleData } from '@angular/common';
 })
 export class JournalNotesComponent implements OnInit, OnDestroy {
   editor: Editor = new Editor();
-  html = '';
-  isInEditMode = true;
-  currentEntryIndex: number = 0;
-  isNewEntry = false;
-
-  public entries: JournalEntry[] = [
-    {
-      title: 'testtitle',
-      content: 'testcontent',
-      created: new Date(2024, 8, 29),
-    },
-    {
-      title: 'zweiter titel',
-      content: 'zweiter content',
-      created: new Date(2023, 1, 2),
-    },
-  ];
-  currentEntry: JournalEntry = this.entries[this.currentEntryIndex];
-
   toolbar: any = [
     // default value
     ['bold', 'italic'],
@@ -38,25 +20,59 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     [{ heading: ['h3', 'h4', 'h5', 'h6'] }],
   ];
 
-  constructor(private _adapter: DateAdapter<any>) {
+  /** Used to show the interactale form or the display version of an entry. */
+  public isInEditMode = false;
+
+  /** The index of the currently active entry */
+  public currentEntryIndex: number = 0;
+
+  private backupIndex: number = -1;
+  /** Indicates, if the currentEntry is a newly generated one that is still not saved. */
+  public isNewEntry = false;
+
+  /**The array of JournalEntries, synched to the   */
+  public entries: JournalEntry[] = [];
+
+  /** Holds the data for the current entry */
+  public currentEntry: JournalEntry = {
+    title: '',
+    content: '',
+    created: new Date(),
+  };
+
+  constructor(
+    private _adapter: DateAdapter<any>,
+    private dataService: DataService,
+  ) {
     registerLocaleData(localeDe);
+    this.entries = this.dataService.notesData;
   }
 
   ngOnInit(): void {
     this._adapter.setLocale('de');
-  }
+    this.entries = this.dataService.notesData;
+    console.log('JournalNotesComponent: ', this.entries);
 
-  // make sure to destory the editor
-  ngOnDestroy(): void {
-    this.editor.destroy();
+    // if the list is empty, set the currentEntryIndex to -1 to hide the entry-container
+    if (this.entries.length === 0) {
+      this.currentEntryIndex = -1;
+    } else {
+      this.currentEntry = this.entries[0];
+    }
   }
 
-  public activateEntry(index: number): void {
+  /**
+   * Sets the currentEntry variable when being clicked on in the entries list on the left.
+   * @param index The index of the selected entry.
+   */
+  public selectEntry(index: number): void {
     this.currentEntryIndex = index;
-    this.currentEntry = this.entries[index];
+    this.currentEntry = this.getEntryAt(index);
+    this.isNewEntry = false;
     this.isInEditMode = false;
   }
 
+  // DONE
   addEntry(): void {
     this.currentEntry = {
       title: '',
@@ -65,26 +81,37 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     };
     this.isNewEntry = true;
     this.isInEditMode = true;
-    // Hightlight no entry
+    // Hightlight no entry because the placeholder is shown as active
+    this.backupIndex = this.currentEntryIndex;
     this.currentEntryIndex = -1;
   }
 
+  public editEntry(): void {
+    this.isInEditMode = true;
+  }
+
+  // DONE
   public saveEntry(): void {
     if (this.isNewEntry) {
       // Prepend the new JournalEntry
-      this.entries = [this.currentEntry, ...this.entries];
+      this.entries.unshift(this.currentEntry);
       this.isNewEntry = false;
       this.currentEntryIndex = 0;
     }
     this.isInEditMode = false;
+    this.entries[this.currentEntryIndex] = this.currentEntry;
+    this.uploadNotes();
   }
 
   public discardEntry(): void {
     if (this.isNewEntry) {
-      // this.currentEntryIndex = this.entries.length - 1;
+      this.currentEntryIndex = this.backupIndex;
       this.isNewEntry = false;
     }
-    this.currentEntry = this.entries[this.currentEntryIndex];
+    if (this.entries.length > 0) {
+      // Reset the currentEntry to the last saved version
+      this.currentEntry = this.getEntryAt(this.currentEntryIndex);
+    }
     this.isInEditMode = false;
   }
 
@@ -94,7 +121,21 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
       this.currentEntryIndex = -1;
     } else {
       this.currentEntryIndex = Math.max(this.currentEntryIndex - 1, 0);
-      this.currentEntry = this.entries[this.currentEntryIndex];
+      this.currentEntry = this.getEntryAt(this.currentEntryIndex);
     }
+    this.uploadNotes();
+  }
+
+  private getEntryAt(index: number): JournalEntry {
+    return JSON.parse(JSON.stringify(this.entries[index]));
+  }
+
+  private uploadNotes(): void {
+    console.log('Uploading notes to the server: ', this.entries);
+    this.dataService.notesData = this.entries;
+  }
+
+  ngOnDestroy(): void {
+    this.editor.destroy();
   }
 }

+ 7 - 2
src/services/data/data.service.ts

@@ -149,7 +149,12 @@ export class DataService {
 
     // Notes
 
-    this.notesData = notesData;
+    if (!Array.isArray(notesData.data)) {
+      this.notesData = [];
+      console.log('migrated notes data to array');
+    } else {
+      this.notesData = notesData.data;
+    }
   }
 
   // #endregion
@@ -1088,7 +1093,7 @@ export class DataService {
 
   public set notesData(newValue: JournalEntry[]) {
     this._notesData = newValue;
-    this.setData('notes', newValue);
+    this.setData('notes', { data: newValue });
   }
 
   // #endregion