-
-
Plan
-
-
-
{{areasMap?.get(item.area_key)?.name}}
-
#{{index}}
-
+
+
Auto scroll to end on add to end
+
Reverse display:
+
+
+
Plan
+
+
+
+
{{areasMap?.get(item.area_key)?.name}}
+
Act {{areasMap?.get(item.area_key)?.act}}
+
+
#{{planIndexOf(item)}}
+
+ Place at end of list
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/app/editor/editor.component.scss b/src/app/editor/editor.component.scss
index 7388d2b..ee2cdc4 100644
--- a/src/app/editor/editor.component.scss
+++ b/src/app/editor/editor.component.scss
@@ -1,41 +1,54 @@
-:host {
- height: 100%;
-}
+:host {}
.container {
width: 400px;
max-width: 100%;
margin: 0 25px 25px 0;
- display: inline-block;
- vertical-align: top;
- flex-grow: 1 1 auto;
+ display: flex;
+ flex-direction: column;
+ max-height: 100%;
+ overflow: hidden;
}
.list {
- border: solid 1px #ccc;
- min-height: 60px;
background: white;
- border-radius: 4px;
+ border: solid 1px #ccc;
display: block;
- padding-bottom: 50px;
+ border-radius: 4px;
+ min-height: 60px;
+ max-height: 100%;
+ max-width: 100%;
overflow: auto;
+}
+
+.innerList {
+ position: relative;
+ min-height: 60px;
max-height: 100%;
+ max-width: 100%;
+ width: 100%;
}
.box {
- padding: 10px 5px;
+ position: relative;
border-bottom: solid 1px #ccc;
color: rgba(0, 0, 0, 0.87);
display: flex;
- flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
cursor: move;
- background: white;
+ background-color: white;
font-size: 14px;
+ padding: 20px 20px 20px 5px;
+ width: 100%;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.1);
+ }
}
+
.cdk-drag-preview {
box-sizing: border-box;
border-radius: 4px;
@@ -60,9 +73,10 @@
transition: transform 125ms cubic-bezier(0, 0, 0.2, 1);
}
-
.editor-container {
display: flex;
flex-direction: row;
+ box-sizing: border-box;
height: 100%;
+ overflow: hidden;
}
\ No newline at end of file
diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts
index 4bce600..546bbbb 100644
--- a/src/app/editor/editor.component.ts
+++ b/src/app/editor/editor.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import {
CdkDrag,
@@ -15,6 +15,11 @@ import { WorldAreaService } from '../services/world-area.service';
import { FormsModule } from '@angular/forms';
import { Fuzzr } from '../fuzzr/fuzzr';
+interface Act {
+ value: number;
+ name: string;
+}
+
@Component({
selector: 'plan-editor',
templateUrl: './editor.component.html',
@@ -36,13 +41,22 @@ export class EditorComponent implements OnInit {
areaSearchString: string = "";
planSearchString: string = "";
planFuzzer: Fuzzr;
+ filterAct: Act;
+ planFilterAct: Act;
+ acts: Act[];
+ @ViewChild('planList') planListElement!: ElementRef;
+ autoScrollToEnd: boolean;
+ reverseDisplay: boolean;
- constructor(public worldAreaService: WorldAreaService) {
+
+ constructor(public worldAreaService: WorldAreaService, private cdr: ChangeDetectorRef) {
this.plan = {
plan: [],
current: 0,
}
+ this.autoScrollToEnd = false;
+
this.planFuzzer = new Fuzzr(this.plan.plan, {
toString: (e: PlanElement) => {
return this.areasMap?.get(e.area_key)?.name;
@@ -50,6 +64,20 @@ export class EditorComponent implements OnInit {
});
this.planAreas = [];
+
+ this.reverseDisplay = false;
+
+ this.acts = [];
+ for (let i = 0; i <= 10; i++) {
+ if (i == 0) {
+ this.acts.push({ value: i, name: "All" });
+ } else {
+ this.acts.push({ value: i, name: "Act " + i.toString() });
+ }
+ }
+
+ this.filterAct = this.acts[0];
+ this.planFilterAct = this.acts[0];
}
ngOnInit(): void {
@@ -60,14 +88,26 @@ export class EditorComponent implements OnInit {
}
dropHandler(event: CdkDragDrop
| CdkDragDrop) {
- if (event.previousContainer === event.container) {
- moveItemInArray(this.plan.plan, event.previousIndex, event.currentIndex);
+ if (event.previousContainer === event.container && !isWorldAreaEvent(event)) {
+ const realCurrent = this.plan.plan.indexOf(event.previousContainer.data[event.currentIndex]);
+ const realPrev = this.plan.plan.indexOf(event.previousContainer.data[event.previousIndex]);
+ moveItemInArray(this.plan.plan, realPrev, realCurrent);
} else
- if (this.plan && this.areas) {
- this.plan.plan.splice(event.currentIndex, 0, this.planItemFromArea(this.areas[event.previousIndex]));
+ if (this.plan && this.areas && isWorldAreaEvent(event)) {
+ this.plan.plan.splice(event.currentIndex, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
}
}
+ dropEndHandler(event: CdkDragDrop | CdkDragDrop) {
+ if (isWorldAreaEvent(event) && this.areas) {
+ this.plan.plan.splice(this.plan.plan.length, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
+ this.scrollToEnd();
+ } else {
+ moveItemInArray(this.plan.plan, event.previousIndex, this.plan.plan.length);
+ this.scrollToEnd();
+ }
+ }
+
planItemFromArea(area: WorldArea): PlanElement {
return {
area_key: area.named_id,
@@ -75,22 +115,59 @@ export class EditorComponent implements OnInit {
};
}
- filterAreas(searchString: string) {
- if (searchString !== "") {
-
- return this.worldAreaService.matcher?.search(searchString).map(({ item }) => {
+ filterAreas() {
+ if (this.areaSearchString !== "" || this.filterAct.value != 0) {
+ return this.worldAreaService.matcher!.search(this.areaSearchString).map(({ item }) => {
return item[1];
- });
+ }).filter(item => item.act == this.filterAct.value || this.filterAct.value == 0);
} else {
- return this.areas;
+ return this.areas!;
}
}
- filterPlanElements(searchString: string) {
- if (searchString !== "") {
- return this.planFuzzer.search(searchString).map(({item}) => item);
+ scrollToEnd() {
+ if(! this.autoScrollToEnd) {
+ return;
+ }
+ this.cdr.detectChanges();
+ if (!this.reverseDisplay) {
+ this.planListElement.nativeElement.scrollTop = this.planListElement.nativeElement.scrollHeight;
+ } else {
+ this.planListElement.nativeElement.scrollTop = 0;
+ }
+ }
+
+ doubleClickArea(item: WorldArea) {
+ this.plan.plan.splice(this.plan.plan.length, 0, this.planItemFromArea(item));
+ this.scrollToEnd();
+ }
+
+ filterPlanElements() {
+ const value = (): any[] => {
+ if (this.planSearchString !== "" || this.planFilterAct.value != 0) {
+ return this.planFuzzer.search(this.planSearchString).map(({ item }) => item).filter(item => {
+ return this.areasMap?.get(item.area_key)?.act == this.planFilterAct.value || this.planFilterAct.value == 0;
+ });
+ } else {
+ return this.plan.plan;
+ }
+ }
+
+ if (this.reverseDisplay) {
+ return value().slice().reverse();
} else {
- return this.plan.plan;
+ return value();
}
}
+
+ planIndexOf(planElement: PlanElement) {
+ const index = this.plan.plan.indexOf(planElement);
+ console.log("plan element", planElement, "index", index);
+ return index;
+ }
}
+
+
+function isWorldAreaEvent(event: any): event is CdkDragDrop {
+ return (event.previousContainer.data.length > 0 && 'connections_world_areas_keys' in event.previousContainer.data[0]);
+}
\ No newline at end of file
diff --git a/src/app/models/plan.ts b/src/app/models/plan.ts
index 4775501..78f7373 100644
--- a/src/app/models/plan.ts
+++ b/src/app/models/plan.ts
@@ -8,5 +8,4 @@ export interface Plan {
export interface PlanElement {
area_key: string;
notes?: string;
- index?: number;
}
\ No newline at end of file
diff --git a/src/app/services/world-area.service.ts b/src/app/services/world-area.service.ts
index 070de32..2cb9328 100644
--- a/src/app/services/world-area.service.ts
+++ b/src/app/services/world-area.service.ts
@@ -16,7 +16,7 @@ export class WorldAreaService {
constructor(private zone: NgZone) {
from(invoke