💄 trip: display selected item position on map, 💄 trip: grouped table mode, 💄 trip: fix price display, 🐛 trip: fix item edit on day change
This commit is contained in:
parent
1217052d34
commit
d0d30a134f
@ -39,7 +39,7 @@ import {
|
|||||||
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, DecimalPipe } 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 { LinkifyPipe } from "../../shared/linkify.pipe";
|
||||||
@ -60,6 +60,7 @@ import { Settings } from "../../types/settings";
|
|||||||
FloatLabelModule,
|
FloatLabelModule,
|
||||||
TableModule,
|
TableModule,
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
|
DecimalPipe,
|
||||||
],
|
],
|
||||||
templateUrl: "./trip.component.html",
|
templateUrl: "./trip.component.html",
|
||||||
styleUrls: ["./trip.component.scss"],
|
styleUrls: ["./trip.component.scss"],
|
||||||
@ -71,6 +72,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
places: Place[] = [];
|
places: Place[] = [];
|
||||||
flattenedTripItems: FlattenedTripItem[] = [];
|
flattenedTripItems: FlattenedTripItem[] = [];
|
||||||
selectedItem?: TripItem & { status?: TripStatus };
|
selectedItem?: TripItem & { status?: TripStatus };
|
||||||
|
tableExpandableMode = false;
|
||||||
|
|
||||||
isMapFullscreen = false;
|
isMapFullscreen = false;
|
||||||
totalPrice = 0;
|
totalPrice = 0;
|
||||||
@ -80,7 +82,8 @@ export class TripComponent implements AfterViewInit {
|
|||||||
|
|
||||||
map?: L.Map;
|
map?: L.Map;
|
||||||
markerClusterGroup?: L.MarkerClusterGroup;
|
markerClusterGroup?: L.MarkerClusterGroup;
|
||||||
hoveredElement?: HTMLElement;
|
tripMapTemporaryMarker?: L.Marker;
|
||||||
|
tripMapHoveredElement?: HTMLElement;
|
||||||
tripMapAntLayer?: L.FeatureGroup;
|
tripMapAntLayer?: L.FeatureGroup;
|
||||||
tripMapAntLayerDayID?: number;
|
tripMapAntLayerDayID?: number;
|
||||||
|
|
||||||
@ -338,9 +341,16 @@ export class TripComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetPlaceHighlightMarker() {
|
resetPlaceHighlightMarker() {
|
||||||
if (!this.hoveredElement) return;
|
if (this.tripMapHoveredElement) {
|
||||||
this.hoveredElement.classList.remove("listHover");
|
this.tripMapHoveredElement.classList.remove("listHover");
|
||||||
this.hoveredElement = undefined;
|
this.tripMapHoveredElement = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.tripMapTemporaryMarker) {
|
||||||
|
this.map?.removeLayer(this.tripMapTemporaryMarker);
|
||||||
|
this.tripMapTemporaryMarker = undefined;
|
||||||
|
}
|
||||||
|
this.resetMapBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
placeHighlightMarker(lat: number, lng: number) {
|
placeHighlightMarker(lat: number, lng: number) {
|
||||||
@ -353,12 +363,23 @@ export class TripComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!marker) return;
|
if (!marker) {
|
||||||
|
// TripItem without place, but latlng
|
||||||
|
const item = {
|
||||||
|
text: this.selectedItem?.text || "",
|
||||||
|
lat: lat,
|
||||||
|
lng: lng,
|
||||||
|
};
|
||||||
|
this.tripMapTemporaryMarker = tripDayMarker(item).addTo(this.map!);
|
||||||
|
this.map?.fitBounds([[lat, lng]], { padding: [30, 30] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const markerElement = marker.getElement() as HTMLElement; // search for Marker. If 'null', is inside Cluster
|
const markerElement = marker.getElement() as HTMLElement; // search for Marker. If 'null', is inside Cluster
|
||||||
if (markerElement) {
|
if (markerElement) {
|
||||||
// marker, not clustered
|
// marker, not clustered
|
||||||
markerElement.classList.add("listHover");
|
markerElement.classList.add("listHover");
|
||||||
this.hoveredElement = markerElement;
|
this.tripMapHoveredElement = markerElement;
|
||||||
} else {
|
} else {
|
||||||
// marker is clustered
|
// marker is clustered
|
||||||
const parentCluster = (this.markerClusterGroup as any).getVisibleParent(
|
const parentCluster = (this.markerClusterGroup as any).getVisibleParent(
|
||||||
@ -368,18 +389,22 @@ export class TripComponent implements AfterViewInit {
|
|||||||
const clusterEl = parentCluster.getElement();
|
const clusterEl = parentCluster.getElement();
|
||||||
if (clusterEl) {
|
if (clusterEl) {
|
||||||
clusterEl.classList.add("listHover");
|
clusterEl.classList.add("listHover");
|
||||||
this.hoveredElement = clusterEl;
|
this.tripMapHoveredElement = clusterEl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetDayHighlight() {
|
||||||
|
this.map?.removeLayer(this.tripMapAntLayer!);
|
||||||
|
this.tripMapAntLayerDayID = undefined;
|
||||||
|
this.tripMapAntLayer = undefined;
|
||||||
|
this.resetMapBounds();
|
||||||
|
}
|
||||||
|
|
||||||
toggleTripDaysHighlight() {
|
toggleTripDaysHighlight() {
|
||||||
if (this.tripMapAntLayerDayID == -1) {
|
if (this.tripMapAntLayerDayID == -1) {
|
||||||
this.map?.removeLayer(this.tripMapAntLayer!);
|
this.resetDayHighlight();
|
||||||
this.tripMapAntLayerDayID = undefined;
|
|
||||||
this.tripMapAntLayer = undefined;
|
|
||||||
this.resetMapBounds();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.trip) return;
|
if (!this.trip) return;
|
||||||
@ -497,10 +522,7 @@ export class TripComponent implements AfterViewInit {
|
|||||||
toggleTripDayHighlightPathDay(day_id: number) {
|
toggleTripDayHighlightPathDay(day_id: number) {
|
||||||
// Click on the currently displayed day: remove
|
// Click on the currently displayed day: remove
|
||||||
if (this.tripMapAntLayerDayID == day_id) {
|
if (this.tripMapAntLayerDayID == day_id) {
|
||||||
this.map?.removeLayer(this.tripMapAntLayer!);
|
this.resetDayHighlight();
|
||||||
this.tripMapAntLayerDayID = undefined;
|
|
||||||
this.tripMapAntLayer = undefined;
|
|
||||||
this.resetMapBounds();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,44 +1046,39 @@ export class TripComponent implements AfterViewInit {
|
|||||||
updateItemFromTrip(old: TripItem, updated: TripItem): void {
|
updateItemFromTrip(old: TripItem, updated: TripItem): void {
|
||||||
if (!this.trip) return;
|
if (!this.trip) return;
|
||||||
|
|
||||||
if (old.day_id != updated.day_id) {
|
if (old.day_id !== updated.day_id) {
|
||||||
const prevDayIdx = this.trip.days.findIndex((d) => d.id == old.day_id);
|
const oldDay = this.trip.days.find((d) => d.id === old.day_id);
|
||||||
if (prevDayIdx === -1) {
|
if (oldDay) {
|
||||||
const prevDay = this.trip.days[prevDayIdx];
|
oldDay.items = oldDay.items.filter((i) => i.id !== old.id);
|
||||||
const prevItemIdx = prevDay.items.findIndex((i) => i.id == updated.id);
|
|
||||||
if (prevItemIdx != -1) prevDay.items.splice(prevItemIdx, 1);
|
|
||||||
this.dayStatsCache.delete(old.day_id);
|
this.dayStatsCache.delete(old.day_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dayIdx = this.trip.days.findIndex((d) => d.id == updated.day_id);
|
const newDay = this.trip.days.find((d) => d.id === updated.day_id);
|
||||||
if (dayIdx != -1) {
|
if (newDay) {
|
||||||
const day = this.trip.days[dayIdx];
|
const itemIdx = newDay.items.findIndex((i) => i.id === updated.id);
|
||||||
const itemIdx = day.items.findIndex((i) => i.id === updated.id);
|
|
||||||
if (itemIdx !== -1) {
|
if (itemIdx !== -1) {
|
||||||
day.items[itemIdx] = updated;
|
newDay.items[itemIdx] = updated;
|
||||||
|
} else {
|
||||||
|
newDay.items.push(updated);
|
||||||
}
|
}
|
||||||
|
this.dayStatsCache.delete(updated.day_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.flattenTripDayItems();
|
this.flattenTripDayItems();
|
||||||
|
this.computePlacesUsedInTable();
|
||||||
|
const updatedPrice = (updated.price || 0) - (old.price || 0);
|
||||||
|
this.updateTotalPrice(updatedPrice);
|
||||||
|
if (this.tripMapAntLayerDayID) this.resetDayHighlight();
|
||||||
|
if (updated.place?.id || old.place?.id) this.setPlacesAndMarkers();
|
||||||
|
|
||||||
if (this.selectedItem && this.selectedItem.id === old.id)
|
if (this.selectedItem && this.selectedItem.id === old.id) {
|
||||||
this.selectedItem = {
|
this.selectedItem = {
|
||||||
...updated,
|
...updated,
|
||||||
status: updated.status
|
status: updated.status
|
||||||
? this.statusToTripStatus(updated.status as string)
|
? this.statusToTripStatus(updated.status as string)
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
this.dayStatsCache.delete(updated.day_id);
|
}
|
||||||
this.computePlacesUsedInTable();
|
|
||||||
|
|
||||||
const updatedPrice = (updated.price || 0) - (old.price || 0);
|
|
||||||
this.updateTotalPrice(updatedPrice);
|
|
||||||
|
|
||||||
if (this.tripMapAntLayerDayID == updated.day_id)
|
|
||||||
this.toggleTripDayHighlightPathDay(updated.day_id);
|
|
||||||
|
|
||||||
if (updated.place?.id || old.place?.id) this.setPlacesAndMarkers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItemFromTrip(item: TripItem): void {
|
removeItemFromTrip(item: TripItem): void {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user