💄 Create place from a Trip, Display status indicator, Minor fixes
This commit is contained in:
parent
25cf9128fc
commit
f4e5c7e4d7
@ -45,8 +45,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<section class="p-4 print:px-1 grid md:grid-cols-3 gap-4 print:block">
|
<section class="p-4 print:px-1 grid lg:grid-cols-3 gap-4 print:block">
|
||||||
<div class="p-4 shadow self-start rounded-md md:col-span-2 max-w-screen print:col-span-full">
|
<div class="p-4 shadow self-start rounded-md lg:col-span-2 max-w-screen print:col-span-full">
|
||||||
<div [class.sticky]="!isMapFullscreen"
|
<div [class.sticky]="!isMapFullscreen"
|
||||||
class="top-0 z-10 bg-white p-2 mb-2 flex justify-between items-center dark:bg-surface-900">
|
class="top-0 z-10 bg-white p-2 mb-2 flex justify-between items-center dark:bg-surface-900">
|
||||||
<div>
|
<div>
|
||||||
@ -91,7 +91,13 @@
|
|||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
<td class="font-mono text-sm">{{ tripitem.time }}</td>
|
<td class="font-mono text-sm">{{ tripitem.time }}</td>
|
||||||
<td class="max-w-60 truncate">{{ tripitem.text }}</td>
|
<td class="relative max-w-60 truncate">
|
||||||
|
<div class="relative">
|
||||||
|
{{ tripitem.text }}
|
||||||
|
@if (tripitem.status) {<div class="block xl:hidden absolute top-0 -left-1.5 size-1.5 rounded-full"
|
||||||
|
[style.background]="tripitem.status.color"></div>}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td class="relative">
|
<td class="relative">
|
||||||
@if (tripitem.place) {
|
@if (tripitem.place) {
|
||||||
<div class="ml-7 print:ml-0 max-w-24 truncate print:whitespace-normal">
|
<div class="ml-7 print:ml-0 max-w-24 truncate print:whitespace-normal">
|
||||||
@ -144,21 +150,25 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-4 sticky top-4 self-start max-w-screen print:hidden">
|
<div class="flex flex-col gap-4 sticky top-4 self-start max-w-screen print:hidden">
|
||||||
@if (selectedItem) {
|
@if (selectedItem) {
|
||||||
<div class="p-4 w-full min-h-20 md:max-h-[600px] rounded-md shadow text-center">
|
<div class="p-4 w-full max-w-full min-h-20 md:max-h-[600px] rounded-md shadow text-center">
|
||||||
<div class="flex items-center justify-between px-2">
|
<div class="flex justify-between items-center mb-3">
|
||||||
<div class="hidden md:flex h-20 w-32">
|
<div class="p-2 flex items-center gap-4 w-full max-w-full">
|
||||||
@if (selectedItem.place) {
|
@if (selectedItem.place) {
|
||||||
<img [src]="selectedItem.place.image || selectedItem.place.category.image"
|
<img [src]="selectedItem.place.image || selectedItem.place.category.image"
|
||||||
class="h-full w-full rounded-md object-cover" />
|
class="hidden md:flex object-cover rounded-md h-20 w-32" />
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2 class="text-xl md:text-3xl font-semibold mb-0 truncate max-w-96 md:mx-auto">{{ selectedItem.text }}</h2>
|
<div class="flex items-center justify-between gap-2 w-full">
|
||||||
<div class="flex items-center gap-2">
|
<h1 class="text-start font-semibold mb-0 line-clamp-1 md:text-xl">{{ selectedItem.text }}
|
||||||
<p-button icon="pi pi-trash" [disabled]="trip?.archived" severity="danger" (click)="deleteItem(selectedItem)"
|
</h1>
|
||||||
text />
|
|
||||||
<p-button icon="pi pi-pencil" [disabled]="trip?.archived" (click)="editItem(selectedItem)" text />
|
<div class="flex items-center gap-2 flex-none">
|
||||||
<p-button icon="pi pi-times" [disabled]="trip?.archived" (click)="selectedItem = undefined" text />
|
<p-button icon="pi pi-trash" [disabled]="trip?.archived" severity="danger"
|
||||||
|
(click)="deleteItem(selectedItem)" text />
|
||||||
|
<p-button icon="pi pi-pencil" [disabled]="trip?.archived" (click)="editItem(selectedItem)" text />
|
||||||
|
<p-button icon="pi pi-times" [disabled]="trip?.archived" (click)="selectedItem = undefined" text />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -176,28 +186,21 @@
|
|||||||
@if (selectedItem.place) {
|
@if (selectedItem.place) {
|
||||||
<div class="rounded-md shadow p-4">
|
<div class="rounded-md shadow p-4">
|
||||||
<p class="font-bold mb-1">Place</p>
|
<p class="font-bold mb-1">Place</p>
|
||||||
<div class="truncate">{{ selectedItem.place.name }}</div>
|
<div class="text-sm text-gray-500 truncate">{{ selectedItem.place.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (selectedItem.comment) {
|
@if (selectedItem.comment) {
|
||||||
<div class="md:col-span-2 rounded-md shadow p-4">
|
<div class="md:col-span-2 rounded-md shadow p-4">
|
||||||
<p class="font-bold mb-1">Comment</p>
|
<p class="font-bold mb-1">Comment</p>
|
||||||
<p class="text-sm text-gray-500 whitespace-pre-line">{{ selectedItem.comment }}</p>
|
<p class="text-sm text-gray-500 whitespace-pre-line" [innerHTML]="selectedItem.comment | linkify"></p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (selectedItem.lat) {
|
@if (selectedItem.lat) {
|
||||||
<div class="rounded-md shadow p-4">
|
<div class="rounded-md shadow p-4">
|
||||||
<p class="font-bold mb-1">Latitude</p>
|
<p class="font-bold mb-1 truncate">Latitude, Longitude</p>
|
||||||
<p class="text-sm text-gray-500">{{ selectedItem.lat }}</p>
|
<p class="text-sm text-gray-500 truncate">{{ selectedItem.lat }}, {{ selectedItem.lng }}</p>
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (selectedItem.lng) {
|
|
||||||
<div class="rounded-md shadow p-4">
|
|
||||||
<p class="font-bold mb-1">Longitude</p>
|
|
||||||
<p class="text-sm text-gray-500">{{ selectedItem.lng }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +261,8 @@
|
|||||||
} @placeholder (minimum 0.4s) {
|
} @placeholder (minimum 0.4s) {
|
||||||
<p-skeleton height="1.75rem" width="2.5rem" class="mr-1" />
|
<p-skeleton height="1.75rem" width="2.5rem" class="mr-1" />
|
||||||
}
|
}
|
||||||
<p-button icon="pi pi-plus" [disabled]="trip?.archived" (click)="manageTripPlaces()" text />
|
<p-button icon="pi pi-plus" [disabled]="trip?.archived" (click)="addPlace()" text />
|
||||||
|
<p-button icon="pi pi-list-check" [disabled]="trip?.archived" (click)="manageTripPlaces()" text />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -275,8 +279,8 @@
|
|||||||
<span class="text-xs text-gray-500 truncate">{{ p.place }}</span>
|
<span class="text-xs text-gray-500 truncate">{{ p.place }}</span>
|
||||||
|
|
||||||
<div class="flex gap-0.5">
|
<div class="flex gap-0.5">
|
||||||
<span
|
<span [style.color]="p.category.color" [style.background-color]="p.category.color + '1A'"
|
||||||
class="bg-blue-100 text-blue-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded flex gap-2 items-center truncate dark:bg-blue-100/85"><i
|
class="text-xs font-medium me-2 px-2.5 py-0.5 rounded flex gap-2 items-center truncate"><i
|
||||||
class="pi pi-box text-xs"></i>{{ p.category.name }}</span>
|
class="pi pi-box text-xs"></i>{{ p.category.name }}</span>
|
||||||
|
|
||||||
@if (isPlaceUsed(p.id)) {
|
@if (isPlaceUsed(p.id)) {
|
||||||
|
|||||||
@ -28,13 +28,15 @@ import { TripPlaceSelectModalComponent } from "../../modals/trip-place-select-mo
|
|||||||
import { TripCreateDayModalComponent } from "../../modals/trip-create-day-modal/trip-create-day-modal.component";
|
import { TripCreateDayModalComponent } from "../../modals/trip-create-day-modal/trip-create-day-modal.component";
|
||||||
import { TripCreateDayItemModalComponent } from "../../modals/trip-create-day-item-modal/trip-create-day-item-modal.component";
|
import { TripCreateDayItemModalComponent } from "../../modals/trip-create-day-item-modal/trip-create-day-item-modal.component";
|
||||||
import { TripCreateItemsModalComponent } from "../../modals/trip-create-items-modal/trip-create-items-modal.component";
|
import { TripCreateItemsModalComponent } from "../../modals/trip-create-items-modal/trip-create-items-modal.component";
|
||||||
import { forkJoin, map, Observable } from "rxjs";
|
import { combineLatest, forkJoin, map, Observable, tap } from "rxjs";
|
||||||
import { YesNoModalComponent } from "../../modals/yes-no-modal/yes-no-modal.component";
|
import { YesNoModalComponent } from "../../modals/yes-no-modal/yes-no-modal.component";
|
||||||
import { UtilsService } from "../../services/utils.service";
|
import { UtilsService } from "../../services/utils.service";
|
||||||
import { TripCreateModalComponent } from "../../modals/trip-create-modal/trip-create-modal.component";
|
import { TripCreateModalComponent } from "../../modals/trip-create-modal/trip-create-modal.component";
|
||||||
import { AsyncPipe } from "@angular/common";
|
import { AsyncPipe } from "@angular/common";
|
||||||
import { MenuItem } from "primeng/api";
|
import { MenuItem } from "primeng/api";
|
||||||
import { MenuModule } from "primeng/menu";
|
import { MenuModule } from "primeng/menu";
|
||||||
|
import { LinkifyPipe } from "../../shared/linkify.pipe";
|
||||||
|
import { PlaceCreateModalComponent } from "../../modals/place-create-modal/place-create-modal.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-trip",
|
selector: "app-trip",
|
||||||
@ -46,6 +48,7 @@ import { MenuModule } from "primeng/menu";
|
|||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
InputTextModule,
|
InputTextModule,
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
|
LinkifyPipe,
|
||||||
FloatLabelModule,
|
FloatLabelModule,
|
||||||
TableModule,
|
TableModule,
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
@ -171,33 +174,36 @@ export class TripComponent implements AfterViewInit {
|
|||||||
this.route.paramMap.subscribe((params) => {
|
this.route.paramMap.subscribe((params) => {
|
||||||
const id = params.get("id");
|
const id = params.get("id");
|
||||||
if (id) {
|
if (id) {
|
||||||
this.apiService.getTrip(+id).subscribe({
|
combineLatest({
|
||||||
next: (trip) => {
|
trip: this.apiService.getTrip(+id),
|
||||||
this.trip = trip;
|
settings: this.apiService.getSettings(),
|
||||||
this.sortTripDays();
|
})
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(trip.days);
|
.pipe(
|
||||||
|
tap(({ trip, settings }) => {
|
||||||
|
this.trip = trip;
|
||||||
|
this.flattenTripDayItems();
|
||||||
|
this.updateTotalPrice();
|
||||||
|
|
||||||
this.updateTotalPrice();
|
let contentMenuItems = [
|
||||||
|
{
|
||||||
let contentMenuItems = [
|
text: "Copy coordinates",
|
||||||
{
|
callback: (e: any) => {
|
||||||
text: "Copy coordinates",
|
const latlng = e.latlng;
|
||||||
callback: (e: any) => {
|
navigator.clipboard.writeText(
|
||||||
const latlng = e.latlng;
|
`${parseFloat(latlng.lat).toFixed(5)}, ${parseFloat(latlng.lng).toFixed(5)}`,
|
||||||
navigator.clipboard.writeText(
|
);
|
||||||
`${parseFloat(latlng.lat).toFixed(5)}, ${parseFloat(latlng.lng).toFixed(5)}`,
|
},
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
];
|
||||||
];
|
this.map = createMap(contentMenuItems, settings.tile_layer);
|
||||||
this.map = createMap(contentMenuItems);
|
this.markerClusterGroup = createClusterGroup().addTo(this.map);
|
||||||
this.markerClusterGroup = createClusterGroup().addTo(this.map);
|
this.setPlacesAndMarkers();
|
||||||
this.setPlacesAndMarkers();
|
|
||||||
|
|
||||||
this.map.setView([48.107, -2.988]);
|
this.map.setView([48.107, -2.988]);
|
||||||
this.resetMapBounds();
|
this.resetMapBounds();
|
||||||
},
|
}),
|
||||||
});
|
)
|
||||||
|
.subscribe();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -249,8 +255,9 @@ export class TripComponent implements AfterViewInit {
|
|||||||
return this.statuses.find((s) => s.label == status) as TripStatus;
|
return this.statuses.find((s) => s.label == status) as TripStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
flattenTripDayItems(days: TripDay[]): FlattenedTripItem[] {
|
flattenTripDayItems() {
|
||||||
return days.flatMap((day) =>
|
this.sortTripDays();
|
||||||
|
this.flattenedTripItems = this.trip!.days.flatMap((day) =>
|
||||||
[...day.items]
|
[...day.items]
|
||||||
.sort((a, b) => a.time.localeCompare(b.time))
|
.sort((a, b) => a.time.localeCompare(b.time))
|
||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
@ -270,7 +277,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
makePlacesUsedInTable() {
|
computePlacesUsedInTable() {
|
||||||
this.placesUsedInTable.clear();
|
this.placesUsedInTable.clear();
|
||||||
this.flattenedTripItems.forEach((i) => {
|
this.flattenedTripItems.forEach((i) => {
|
||||||
if (i.place?.id) this.placesUsedInTable.add(i.place.id);
|
if (i.place?.id) this.placesUsedInTable.add(i.place.id);
|
||||||
@ -278,7 +285,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPlacesAndMarkers() {
|
setPlacesAndMarkers() {
|
||||||
this.makePlacesUsedInTable();
|
this.computePlacesUsedInTable();
|
||||||
this.places = this.trip?.places || [];
|
this.places = this.trip?.places || [];
|
||||||
this.places.sort((a, b) => a.name.localeCompare(b.name));
|
this.places.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
@ -636,8 +643,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
this.apiService.postTripDay(day, this.trip?.id!).subscribe({
|
this.apiService.postTripDay(day, this.trip?.id!).subscribe({
|
||||||
next: (day) => {
|
next: (day) => {
|
||||||
this.trip?.days.push(day);
|
this.trip?.days.push(day);
|
||||||
this.sortTripDays();
|
this.flattenTripDayItems();
|
||||||
this.flattenedTripItems.push(...this.flattenTripDayItems([day]));
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -670,11 +676,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
let index = this.trip?.days.findIndex((d) => d.id == day.id);
|
let index = this.trip?.days.findIndex((d) => d.id == day.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.trip?.days.splice(index as number, 1, day);
|
this.trip?.days.splice(index as number, 1, day);
|
||||||
this.sortTripDays();
|
this.flattenTripDayItems();
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
|
||||||
this.trip?.days!,
|
|
||||||
);
|
|
||||||
this.dayStatsCache.delete(day.id);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -700,14 +702,9 @@ export class TripComponent implements AfterViewInit {
|
|||||||
this.apiService.deleteTripDay(this.trip?.id!, day.id).subscribe({
|
this.apiService.deleteTripDay(this.trip?.id!, day.id).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
let index = this.trip?.days.findIndex((d) => d.id == day.id);
|
let index = this.trip?.days.findIndex((d) => d.id == day.id);
|
||||||
if (index != -1) {
|
this.trip?.days.splice(index as number, 1);
|
||||||
this.trip?.days.splice(index as number, 1);
|
this.flattenTripDayItems();
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
this.setPlacesAndMarkers();
|
||||||
this.trip?.days!,
|
|
||||||
);
|
|
||||||
this.dayStatsCache.delete(day.id);
|
|
||||||
this.makePlacesUsedInTable();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -778,18 +775,15 @@ export class TripComponent implements AfterViewInit {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (resp) => {
|
next: (resp) => {
|
||||||
let index = this.trip?.days.findIndex((d) => d.id == item.day_id);
|
let index = this.trip?.days.findIndex((d) => d.id == item.day_id);
|
||||||
if (index != -1) {
|
let td: TripDay = this.trip?.days[index as number]!;
|
||||||
let td: TripDay = this.trip?.days[index as number]!;
|
td.items.push(resp);
|
||||||
td.items.push(resp);
|
this.flattenTripDayItems();
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
|
||||||
this.trip?.days!,
|
if (resp.price) this.updateTotalPrice(resp.price);
|
||||||
);
|
if (resp.place?.id) {
|
||||||
}
|
this.placesUsedInTable.add(resp.place.id);
|
||||||
if (item.price) this.updateTotalPrice(item.price);
|
this.dayStatsCache.delete(resp.day_id);
|
||||||
if (item.place?.id) {
|
|
||||||
this.placesUsedInTable.add(item.place.id);
|
|
||||||
this.setPlacesAndMarkers();
|
this.setPlacesAndMarkers();
|
||||||
this.dayStatsCache.delete(item.day_id);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -829,36 +823,48 @@ export class TripComponent implements AfterViewInit {
|
|||||||
this.apiService
|
this.apiService
|
||||||
.putTripDayItem(it, this.trip?.id!, item.day_id, item.id)
|
.putTripDayItem(it, this.trip?.id!, item.day_id, item.id)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (item) => {
|
next: (new_item) => {
|
||||||
let index = this.trip?.days.findIndex((d) => d.id == item.day_id);
|
if (item.day_id != new_item.day_id) {
|
||||||
if (index != -1) {
|
let previousIndex = this.trip?.days.findIndex(
|
||||||
let td: TripDay = this.trip?.days[index as number]!;
|
(d) => d.id == item.day_id,
|
||||||
td.items.splice(
|
);
|
||||||
td.items.findIndex((i) => i.id == item.id),
|
this.trip?.days[previousIndex as number]!.items.splice(
|
||||||
|
this.trip?.days[previousIndex as number]!.items.findIndex(
|
||||||
|
(i) => i.id == new_item.id,
|
||||||
|
),
|
||||||
1,
|
1,
|
||||||
item,
|
|
||||||
);
|
);
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
|
||||||
this.trip?.days!,
|
|
||||||
);
|
|
||||||
if (this.selectedItem && this.selectedItem.id === item.id)
|
|
||||||
this.selectedItem = {
|
|
||||||
...item,
|
|
||||||
status: item.status
|
|
||||||
? this.statusToTripStatus(item.status as string)
|
|
||||||
: undefined,
|
|
||||||
};
|
|
||||||
this.dayStatsCache.delete(item.day_id);
|
this.dayStatsCache.delete(item.day_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.place?.id) this.placesUsedInTable.add(item.place.id);
|
let index = this.trip?.days.findIndex(
|
||||||
const updatedPrice = -(item.price || 0) + (it.price || 0);
|
(d) => d.id == new_item.day_id,
|
||||||
|
);
|
||||||
|
let td: TripDay = this.trip?.days[index as number]!;
|
||||||
|
td.items.splice(
|
||||||
|
td.items.findIndex((i) => i.id == new_item.id),
|
||||||
|
1,
|
||||||
|
new_item,
|
||||||
|
);
|
||||||
|
this.flattenTripDayItems();
|
||||||
|
if (this.selectedItem && this.selectedItem.id === item.id)
|
||||||
|
this.selectedItem = {
|
||||||
|
...new_item,
|
||||||
|
status: new_item.status
|
||||||
|
? this.statusToTripStatus(new_item.status as string)
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
this.dayStatsCache.delete(new_item.day_id);
|
||||||
|
|
||||||
|
this.computePlacesUsedInTable();
|
||||||
|
const updatedPrice = -(new_item.price || 0) + (item.price || 0);
|
||||||
this.updateTotalPrice(updatedPrice);
|
this.updateTotalPrice(updatedPrice);
|
||||||
|
|
||||||
if (this.tripMapAntLayerDayID == item.day_id)
|
if (this.tripMapAntLayerDayID == new_item.day_id)
|
||||||
this.toggleTripDayHighlightPathDay(item.day_id);
|
this.toggleTripDayHighlightPathDay(new_item.day_id);
|
||||||
|
|
||||||
if (item.place?.id || it.place?.id) this.setPlacesAndMarkers();
|
if (new_item.place?.id || item.place?.id)
|
||||||
|
this.setPlacesAndMarkers();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -887,25 +893,23 @@ export class TripComponent implements AfterViewInit {
|
|||||||
let index = this.trip?.days.findIndex(
|
let index = this.trip?.days.findIndex(
|
||||||
(d) => d.id == item.day_id,
|
(d) => d.id == item.day_id,
|
||||||
);
|
);
|
||||||
if (index != -1) {
|
|
||||||
let td: TripDay = this.trip?.days[index as number]!;
|
let td: TripDay = this.trip?.days[index as number]!;
|
||||||
td.items.splice(
|
td.items.splice(
|
||||||
td.items.findIndex((i) => i.id == item.id),
|
td.items.findIndex((i) => i.id == item.id),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
this.flattenTripDayItems();
|
||||||
this.trip?.days!,
|
|
||||||
);
|
if (item.place?.id) {
|
||||||
if (item.place?.id) {
|
this.placesUsedInTable.delete(item.place.id);
|
||||||
this.placesUsedInTable.delete(item.place.id);
|
if (item.place.price)
|
||||||
if (item.place.price)
|
this.updateTotalPrice(-item.place.price);
|
||||||
this.updateTotalPrice(-item.place.price);
|
this.setPlacesAndMarkers();
|
||||||
this.setPlacesAndMarkers();
|
|
||||||
}
|
|
||||||
this.dayStatsCache.delete(item.day_id);
|
|
||||||
this.selectedItem = undefined;
|
|
||||||
this.resetPlaceHighlightMarker();
|
|
||||||
}
|
}
|
||||||
|
this.dayStatsCache.delete(item.day_id);
|
||||||
|
this.selectedItem = undefined;
|
||||||
|
this.resetPlaceHighlightMarker();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -942,17 +946,54 @@ export class TripComponent implements AfterViewInit {
|
|||||||
.pipe(
|
.pipe(
|
||||||
map((items) => {
|
map((items) => {
|
||||||
let index = this.trip?.days.findIndex((d) => d.id == day_id);
|
let index = this.trip?.days.findIndex((d) => d.id == day_id);
|
||||||
if (index != -1) {
|
let td: TripDay = this.trip?.days[index as number]!;
|
||||||
let td: TripDay = this.trip?.days[index as number]!;
|
td.items.push(...items);
|
||||||
td.items.push(...items);
|
this.flattenTripDayItems();
|
||||||
this.flattenedTripItems = this.flattenTripDayItems(
|
|
||||||
this.trip?.days!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPlace() {
|
||||||
|
const modal: DynamicDialogRef = this.dialogService.open(
|
||||||
|
PlaceCreateModalComponent,
|
||||||
|
{
|
||||||
|
header: "Create Place",
|
||||||
|
modal: true,
|
||||||
|
appendTo: "body",
|
||||||
|
closable: true,
|
||||||
|
dismissableMask: true,
|
||||||
|
width: "55vw",
|
||||||
|
breakpoints: {
|
||||||
|
"1920px": "70vw",
|
||||||
|
"1260px": "90vw",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
modal.onClose.subscribe({
|
||||||
|
next: (place: Place | null) => {
|
||||||
|
if (!place) return;
|
||||||
|
|
||||||
|
this.apiService.postPlace(place).subscribe({
|
||||||
|
next: (place: Place) => {
|
||||||
|
this.apiService
|
||||||
|
.putTrip(
|
||||||
|
{ place_ids: [place, ...this.places].map((p) => p.id) },
|
||||||
|
this.trip?.id!,
|
||||||
|
)
|
||||||
|
.subscribe({
|
||||||
|
next: (trip) => {
|
||||||
|
this.trip = trip;
|
||||||
|
this.setPlacesAndMarkers();
|
||||||
|
this.resetMapBounds();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user