Browse Source

Implemented new way to add spells to favorites.

Warafear 1 year ago
parent
commit
af84fca633

+ 0 - 2
src/app/journal/journal-spellcards/add-card/add-card.component.scss

@@ -35,12 +35,10 @@
 }
 }
 
 
 .add-card-button {
 .add-card-button {
-    // height: 3rem;
     background-color: var(--primary-color);
     background-color: var(--primary-color);
     border: 1px solid var(--border-color);
     border: 1px solid var(--border-color);
     border-radius: 10px;
     border-radius: 10px;
     box-shadow: var(--shadow);
     box-shadow: var(--shadow);
-    // font-size: 1.25rem;
     font-weight: 600;
     font-weight: 600;
     width: 90%;
     width: 90%;
     margin: 0 0.5rem;
     margin: 0 0.5rem;

+ 3 - 2
src/app/journal/journal-spellcards/journal-spellcards.component.ts

@@ -69,7 +69,7 @@ export class JournalSpellcardsComponent {
   ): void {
   ): void {
     this.modalAccessor.openModal(FullSpellcardComponent, {
     this.modalAccessor.openModal(FullSpellcardComponent, {
       spell: spell,
       spell: spell,
-      isEditable: true,
+      isFromDashboard: false,
     });
     });
     const resultSubscription = this.modalAccessor.result$.subscribe(
     const resultSubscription = this.modalAccessor.result$.subscribe(
       (result) => {
       (result) => {
@@ -77,10 +77,11 @@ export class JournalSpellcardsComponent {
         if (result.state === 'delete') {
         if (result.state === 'delete') {
           this.getSpellList(level).splice(spellIndex, 1);
           this.getSpellList(level).splice(spellIndex, 1);
         } else if (result.state === 'update') {
         } else if (result.state === 'update') {
-          console.log('update');
           setTimeout(() => {
           setTimeout(() => {
             this.openSpellModal(true, level, spellIndex);
             this.openSpellModal(true, level, spellIndex);
           }, 100);
           }, 100);
+        } else if (result.state === 'add') {
+          this.dataAccessor.favoriteSpells.push(spell);
         } else if (result.state !== 'cancel') {
         } else if (result.state !== 'cancel') {
           console.log(result.state);
           console.log(result.state);
           throw new Error('Unexpected result state, please send a bug report.');
           throw new Error('Unexpected result state, please send a bug report.');

+ 16 - 0
src/app/journal/journal-stats/weapons-container/spell-table/spell-table.component.html

@@ -64,6 +64,22 @@
       ></ng-container>
       ></ng-container>
     </div>
     </div>
   </div>
   </div>
+  <input
+    id="typeahead-basic"
+    type="text"
+    [class]="showInput ? 'spellInput' : 'spellInput hidden'"
+    (selectItem)="onSpellSelect($event.item); $event.preventDefault()"
+    [(ngModel)]="newSpellName"
+    [ngbTypeahead]="search"
+    placement="top-start"
+    placeholder="Name des vorbereiteten Zaubers"
+  />
+  <button
+    [class]="showInput ? 'slide-button cancel-button' : 'slide-button'"
+    (click)="showInput = !showInput"
+  >
+    @if(showInput){ Abbrechen} @else { Hinzufügen}
+  </button>
 </div>
 </div>
 
 
 <!-- Templates -->
 <!-- Templates -->

+ 78 - 25
src/app/journal/journal-stats/weapons-container/spell-table/spell-table.component.scss

@@ -1,4 +1,4 @@
-.example-list { 
+.example-list {
   max-width: 100%;
   max-width: 100%;
   min-height: 60px;
   min-height: 60px;
   display: block;
   display: block;
@@ -11,54 +11,57 @@
   margin: 15px 10px;
   margin: 15px 10px;
   color: rgba(0, 0, 0, 0.87);
   color: rgba(0, 0, 0, 0.87);
   display: grid;
   display: grid;
-  grid-template-columns: 6fr .1fr 20fr .1fr 10fr .1fr 8fr .1fr 20fr .1fr 16fr;
+  grid-template-columns: 6fr 0.1fr 20fr 0.1fr 10fr 0.1fr 8fr 0.1fr 20fr 0.1fr 16fr;
   align-items: center;
   align-items: center;
   justify-content: space-between;
   justify-content: space-between;
   box-sizing: border-box;
   box-sizing: border-box;
   cursor: move;
   cursor: move;
   background: var(--primary-color-light);
   background: var(--primary-color-light);
-  border-radius: 10px;;
+  border-radius: 10px;
   font-size: 1rem;
   font-size: 1rem;
-  font-weight:600;
+  font-weight: 600;
   text-align: center;
   text-align: center;
-  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
-              0 8px 8px 1px rgba(0, 0, 0, 0.14),
-              0 3px 10px 2px rgba(0, 0, 0, 0.12);
+  box-shadow:
+    0 5px 5px -3px rgba(0, 0, 0, 0.2),
+    0 8px 8px 1px rgba(0, 0, 0, 0.14),
+    0 3px 10px 2px rgba(0, 0, 0, 0.12);
 }
 }
 
 
-.spell-box{
+.spell-box {
   height: 100%;
   height: 100%;
-  display:flex;
+  width: 100%;
+  display: flex;
   flex-direction: column;
   flex-direction: column;
+  position: relative;
 }
 }
 
 
-.heading-list{
+.heading-list {
   flex: 0 0 3rem;
   flex: 0 0 3rem;
   margin: 0.5rem 0.625rem;
   margin: 0.5rem 0.625rem;
   display: grid;
   display: grid;
   grid-template-columns: 6fr 20fr 10fr 8fr 20fr 16fr;
   grid-template-columns: 6fr 20fr 10fr 8fr 20fr 16fr;
-  text-align:center;
+  text-align: center;
   font-weight: 700;
   font-weight: 700;
 }
 }
 
 
-.table-content{
-  flex: 0 0 calc(100% - 4rem);
+.table-content {
+  flex: 0 0 calc(100% - 9rem);
   overflow-y: auto;
   overflow-y: auto;
-    }
+}
 
 
-.bold{
+.bold {
   font-weight: bold;
   font-weight: bold;
 }
 }
 
 
-.small{
-  font-size: .625rem;
+.small {
+  font-size: 0.625rem;
 }
 }
 
 
-.large{
+.large {
   font-size: 1.125rem;
   font-size: 1.125rem;
 }
 }
 
 
-.vertical-line{
+.vertical-line {
   position: relative;
   position: relative;
   width: 1px;
   width: 1px;
   height: 3.5rem;
   height: 3.5rem;
@@ -67,20 +70,70 @@
 .vertical-line::before {
 .vertical-line::before {
   content: "";
   content: "";
   position: absolute;
   position: absolute;
-  top: 15%; 
-  bottom: 15%; 
+  top: 15%;
+  bottom: 15%;
   left: 0;
   left: 0;
   border-left: 1px solid black;
   border-left: 1px solid black;
 }
 }
 
 
+.slide-button {
+  position: absolute;
+  height: 3rem;
+  bottom: 1rem;
+  right: 10%;
+  width: 80%;
+  border-radius: 10px;
+  background: var(--accept);
+  transition: width 0.25s ease-in-out;
+
+  &:hover {
+    background-color: var(--accept-hover);
+  }
+}
+
+.cancel-button {
+  width: 20%;
+  background-color: var(--delete);
+
+  &:hover {
+    background-color: var(--delete-hover);
+  }
+}
+
+.spellInput {
+  position: absolute;
+  height: 3rem;
+  bottom: 1rem;
+  right: 25%;
+  width: 65%;
+  border-radius: 10px;
+}
+
+.hidden {
+  animation: fadeOut 0.25s forwards;
+}
+
+@keyframes fadeOut {
+  0% {
+    visibility: visible;
+  }
+  99% {
+    visibility: visible;
+  }
+  100% {
+    visibility: hidden;
+  }
+}
+
 //// Drag and Drop
 //// Drag and Drop
 
 
 .cdk-drag-preview {
 .cdk-drag-preview {
   box-sizing: border-box;
   box-sizing: border-box;
   border-radius: 10px;
   border-radius: 10px;
-  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
-              0 8px 10px 1px rgba(0, 0, 0, 0.14),
-              0 3px 14px 2px rgba(0, 0, 0, 0.12);
+  box-shadow:
+    0 5px 5px -3px rgba(0, 0, 0, 0.2),
+    0 8px 10px 1px rgba(0, 0, 0, 0.14),
+    0 3px 14px 2px rgba(0, 0, 0, 0.12);
 }
 }
 
 
 .cdk-drag-placeholder {
 .cdk-drag-placeholder {
@@ -97,4 +150,4 @@
 
 
 .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
 .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
   transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
   transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
-}
+}

+ 41 - 1
src/app/journal/journal-stats/weapons-container/spell-table/spell-table.component.ts

@@ -25,6 +25,8 @@ export class SpellTableComponent {
   public spells!: Spell[];
   public spells!: Spell[];
   private preparedSpells!: Spell[];
   private preparedSpells!: Spell[];
   private preparedSpellsNames: string[] = [];
   private preparedSpellsNames: string[] = [];
+  public newSpellName: string = '';
+  public showInput: boolean = false;
 
 
   public attributes: any = {
   public attributes: any = {
     strength: 'STR',
     strength: 'STR',
@@ -61,7 +63,7 @@ export class SpellTableComponent {
   public showFullSpellcard(spellIndex: number): void {
   public showFullSpellcard(spellIndex: number): void {
     this.modalAccessor.openModal(FullSpellcardComponent, {
     this.modalAccessor.openModal(FullSpellcardComponent, {
       spell: this.spells[spellIndex],
       spell: this.spells[spellIndex],
-      isEditable: false,
+      isFromDashboard: true,
     });
     });
     const resultSubscription = this.modalAccessor.result$.subscribe(
     const resultSubscription = this.modalAccessor.result$.subscribe(
       (result) => {
       (result) => {
@@ -120,6 +122,23 @@ export class SpellTableComponent {
     );
     );
   }
   }
 
 
+  public toggleInput(): void {
+    this.showInput = !this.showInput;
+    this.newSpellName = '';
+  }
+
+  public onSpellSelect(spellname: any): void {
+    const newSpell = this.preparedSpells.filter(
+      (spell) => spell.name === spellname
+    );
+    if (newSpell.length !== 1) {
+      throw new Error('Spell not found.');
+    } else {
+      this.addSpell(newSpell[0]);
+    }
+    this.newSpellName = '';
+  }
+
   public addSpell(spell: Spell) {
   public addSpell(spell: Spell) {
     this.spells.push(spell);
     this.spells.push(spell);
     this.updateSpellsInDatabase();
     this.updateSpellsInDatabase();
@@ -173,4 +192,25 @@ export class SpellTableComponent {
       this.computeSpellAttackBonusAndSaveDC();
       this.computeSpellAttackBonusAndSaveDC();
     });
     });
   }
   }
+
+  public search: OperatorFunction<string, readonly string[]> = (
+    text$: Observable<string>
+  ) =>
+    text$.pipe(
+      debounceTime(200),
+      distinctUntilChanged(),
+      map((term) =>
+        term.length < 2
+          ? []
+          : this.preparedSpellsNames
+              .filter((v) => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
+              .filter(
+                (v) =>
+                  !this.spells.some(
+                    (spell) => spell.name.toLowerCase() === v.toLowerCase()
+                  )
+              )
+              .slice(0, 5)
+      )
+    );
 }
 }

+ 3 - 3
src/app/journal/journal-stats/weapons-container/weapons-container.component.html

@@ -17,9 +17,6 @@
   </div>
   </div>
   @switch(active){ @case(1){
   @switch(active){ @case(1){
   <weapon-table #weaponTable></weapon-table>
   <weapon-table #weaponTable></weapon-table>
-  } @case(2){
-  <spell-table #spellTable></spell-table>
-  } }
   <ui-button
   <ui-button
     [type]="'add'"
     [type]="'add'"
     [size]="'xlarge'"
     [size]="'xlarge'"
@@ -27,4 +24,7 @@
     class="button-margin"
     class="button-margin"
     (click)="openModal()"
     (click)="openModal()"
   ></ui-button>
   ></ui-button>
+  } @case(2){
+  <spell-table #spellTable></spell-table>
+  } }
 </div>
 </div>

+ 63 - 90
src/app/journal/journal-stats/weapons-container/weapons-container.component.scss

@@ -1,56 +1,55 @@
-.weapon-spell-container{
+.weapon-spell-container {
   border: solid 1px var(--border-color);
   border: solid 1px var(--border-color);
-    // background-color: var(--field-background-color);
-    box-shadow: var(--shadow-small);
-    border-radius: 10px;
-    height: 35.5rem;
-    display:flex;
-    flex-direction: column;
-}
-
-.tab-row{
-    display: flex;
-    flex: 0 0 3rem;
-    > *{
-        flex: 1 1 0;
-    }
-    > :first-child{
-      border-radius: 10px 0 0 0
-    }
-    > :last-child{
-      border-radius: 0 10px 0 0
-    }
-}
-
-.tab-button{
-    height: 2.25rem;
-    font-size: 1.375rem;
-    font-weight: 600;
-    color: black;
-    border: solid 1px var(--border-color);
-    transition: all 0.25s ease-in-out;
-    background-color: var(--primary-color-light);
-
-    &.active{
-        height: 2.75rem;
-        background-color: var(--primary-color);
-    }
-}
-
-
-weapon-table{
-    // 100% - tabbar height - add button height
-    height: calc(100% - 8rem);
-}
-
-spell-table{
+  // background-color: var(--field-background-color);
+  box-shadow: var(--shadow-small);
+  border-radius: 10px;
+  height: 35.5rem;
+  display: flex;
+  flex-direction: column;
+}
+
+.tab-row {
+  display: flex;
+  flex: 0 0 3rem;
+  > * {
+    flex: 1 1 0;
+  }
+  > :first-child {
+    border-radius: 10px 0 0 0;
+  }
+  > :last-child {
+    border-radius: 0 10px 0 0;
+  }
+}
+
+.tab-button {
+  height: 2.25rem;
+  font-size: 1.375rem;
+  font-weight: 600;
+  color: black;
+  border: solid 1px var(--border-color);
+  transition: all 0.25s ease-in-out;
+  background-color: var(--primary-color-light);
+
+  &.active {
+    height: 2.75rem;
+    background-color: var(--primary-color);
+  }
+}
+
+weapon-table {
   // 100% - tabbar height - add button height
   // 100% - tabbar height - add button height
-    height: calc(100% - 8rem);
+  height: calc(100% - 8rem);
 }
 }
 
 
-.button-margin{
-    margin: 1rem 0rem;
+spell-table {
+  // 100% - tabbar height - add button height
+  height: calc(100% - 3rem);
+  // height: 100%;
+}
 
 
+.button-margin {
+  margin: 1rem 0rem;
 }
 }
 
 
 .example-list {
 .example-list {
@@ -63,12 +62,12 @@ spell-table{
   overflow: hidden;
   overflow: hidden;
 }
 }
 
 
-.damage-list{
+.damage-list {
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
 }
 }
 
 
-.damage-row{
+.damage-row {
   display: flex;
   display: flex;
   flex-direction: row;
   flex-direction: row;
   justify-content: center;
   justify-content: center;
@@ -76,7 +75,6 @@ spell-table{
   gap: 0.1rem;
   gap: 0.1rem;
 }
 }
 
 
-
 .example-box {
 .example-box {
   padding: 20px 10px;
   padding: 20px 10px;
   border-bottom: solid 1px #ccc;
   border-bottom: solid 1px #ccc;
@@ -89,7 +87,7 @@ spell-table{
   cursor: move;
   cursor: move;
   background: white;
   background: white;
   font-size: 14px;
   font-size: 14px;
-  input{
+  input {
     border: none;
     border: none;
     background: transparent;
     background: transparent;
     text-align: center;
     text-align: center;
@@ -98,82 +96,58 @@ spell-table{
 
 
 //////////////// list item elemens ////////////////
 //////////////// list item elemens ////////////////
 
 
-
-
-
-
-
-
-
-
-
-
-
-
 //////////////////////////////////////////////////
 //////////////////////////////////////////////////
 
 
-
-
-
-.vertical-line{
+.vertical-line {
   width: 1px;
   width: 1px;
   height: 3rem;
   height: 3rem;
-  border-left: solid 1px rgb(121, 121, 121)
+  border-left: solid 1px rgb(121, 121, 121);
 }
 }
 
 
-.weapon-type{
+.weapon-type {
   width: 2rem;
   width: 2rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-proficient{
+.weapon-proficient {
   width: 2rem;
   width: 2rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-name{
+.weapon-name {
   width: 6rem;
   width: 6rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-attack-bonus{
+.weapon-attack-bonus {
   width: 2rem;
   width: 2rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-damage{
+.weapon-damage {
   width: 3rem;
   width: 3rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-range{
+.weapon-range {
   width: 4rem;
   width: 4rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-.weapon-edit{
+.weapon-edit {
   width: 3rem;
   width: 3rem;
   text-align: center;
   text-align: center;
 }
 }
 
 
-
-
-
-
-
-
-
-
-
-
 // Drag and Drop
 // Drag and Drop
 
 
 .cdk-drag-preview {
 .cdk-drag-preview {
   box-sizing: border-box;
   box-sizing: border-box;
   border-radius: 4px;
   border-radius: 4px;
-  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
-              0 8px 10px 1px rgba(0, 0, 0, 0.14),
-              0 3px 14px 2px rgba(0, 0, 0, 0.12);
+  box-shadow:
+    0 5px 5px -3px rgba(0, 0, 0, 0.2),
+    0 8px 10px 1px rgba(0, 0, 0, 0.14),
+    0 3px 14px 2px rgba(0, 0, 0, 0.12);
 }
 }
 
 
 .cdk-drag-placeholder {
 .cdk-drag-placeholder {
@@ -191,4 +165,3 @@ spell-table{
 .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
 .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
   transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
   transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
 }
 }
-

+ 4 - 1
src/app/shared-components/full-spellcard/full-spellcard.component.html

@@ -108,7 +108,10 @@
   </div>
   </div>
 
 
   <div class="delete-row">
   <div class="delete-row">
-    @if(isEditable){
+    @if(!isFromDashboard){
+    <button class="add-button" (click)="addToFavorites()">
+      Zu Favoriten hinzufügen
+    </button>
     <button class="edit-button" (click)="update()">Anpassen</button>
     <button class="edit-button" (click)="update()">Anpassen</button>
     <button class="delete-button" (click)="delete()">Löschen</button>
     <button class="delete-button" (click)="delete()">Löschen</button>
     } @else {
     } @else {

+ 10 - 1
src/app/shared-components/full-spellcard/full-spellcard.component.scss

@@ -3,7 +3,7 @@
     border: none;
     border: none;
     border-radius: 10px;
     border-radius: 10px;
     box-shadow: var(--shadow);
     box-shadow: var(--shadow);
-    height: 3rem;
+    height: 4rem;
     width: 8rem;
     width: 8rem;
     font-size: 1.125rem;
     font-size: 1.125rem;
     font-weight: 600;
     font-weight: 600;
@@ -42,3 +42,12 @@
         scale: 1.03;
         scale: 1.03;
     }
     }
 }
 }
+
+.add-button {
+    background: var(--accept);
+    @include button;
+    &:hover {
+        background: var(--accept-hover);
+        scale: 1.03;
+    }
+}

+ 5 - 1
src/app/shared-components/full-spellcard/full-spellcard.component.ts

@@ -9,7 +9,7 @@ import { ModalService } from 'src/services/modal/modal.service';
 })
 })
 export class FullSpellcardComponent {
 export class FullSpellcardComponent {
   @Input() public spell!: Spell;
   @Input() public spell!: Spell;
-  @Input() public isEditable!: boolean;
+  @Input() public isFromDashboard!: boolean;
 
 
   public constructor(private modalAccessor: ModalService) {}
   public constructor(private modalAccessor: ModalService) {}
 
 
@@ -20,4 +20,8 @@ export class FullSpellcardComponent {
   public update(): void {
   public update(): void {
     this.modalAccessor.handleModalClosing('update', undefined);
     this.modalAccessor.handleModalClosing('update', undefined);
   }
   }
+
+  public addToFavorites(): void {
+    this.modalAccessor.handleModalClosing('add', undefined);
+  }
 }
 }

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

@@ -619,6 +619,8 @@ export class DataService {
     ];
     ];
   }
   }
 
 
+  //
+
   private abilities: Ability[] = [
   private abilities: Ability[] = [
     {
     {
       name: 'Feenschritt',
       name: 'Feenschritt',