diff --git a/museum_map/server/api/__init__.py b/museum_map/server/api/__init__.py
index abccde3..2177c70 100644
--- a/museum_map/server/api/__init__.py
+++ b/museum_map/server/api/__init__.py
@@ -8,12 +8,13 @@
from museum_map.__about__ import __tables__, __version__
from museum_map.models import db_session
-from museum_map.server.api import floor_topics, floors, picks, rooms
+from museum_map.server.api import floor_topics, floors, items, picks, rooms
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api")
router.include_router(floors.router)
router.include_router(floor_topics.router)
+router.include_router(items.router)
router.include_router(picks.router)
router.include_router(rooms.router)
diff --git a/museum_map/server/api/floors.py b/museum_map/server/api/floors.py
index 0ee5ae9..fb83f87 100644
--- a/museum_map/server/api/floors.py
+++ b/museum_map/server/api/floors.py
@@ -18,6 +18,7 @@ async def get_floors(dbsession: Annotated[AsyncSession, Depends(db_session)]):
"""Retrieve all floors."""
query = (
select(Floor)
+ .order_by(Floor.level)
.options(selectinload(Floor.rooms))
.options(selectinload(Floor.samples))
.options(selectinload(Floor.topics))
diff --git a/museum_map/server/api/items.py b/museum_map/server/api/items.py
new file mode 100644
index 0000000..d12004e
--- /dev/null
+++ b/museum_map/server/api/items.py
@@ -0,0 +1,23 @@
+"""Routes for accessing the item data."""
+import logging
+from typing import Annotated
+
+from fastapi import APIRouter, Depends, Query
+from sqlalchemy import select
+from sqlalchemy.ext.asyncio import AsyncSession
+from sqlalchemy.orm import selectinload
+
+from museum_map.models import Item, ItemModel, db_session
+
+router = APIRouter(prefix="/items")
+logger = logging.getLogger(__name__)
+
+
+@router.get("/", response_model=list[ItemModel])
+async def get_items(
+ iid: Annotated[list[int] | None, Query()],
+ dbsession: Annotated[AsyncSession, Depends(db_session)],
+):
+ """Retrieve items."""
+ query = select(Item).filter(Item.id.in_(iid)).options(selectinload(Item.group)).options(selectinload(Item.room))
+ return (await dbsession.execute(query)).scalars()
diff --git a/museum_map/server/api/rooms.py b/museum_map/server/api/rooms.py
index c40eb9a..1c44974 100644
--- a/museum_map/server/api/rooms.py
+++ b/museum_map/server/api/rooms.py
@@ -14,10 +14,10 @@
@router.get("/", response_model=list[RoomModel])
-async def get_floors(
+async def get_rooms(
dbsession: Annotated[AsyncSession, Depends(db_session)], rid: Annotated[list[int] | None, Query()] = None
):
- """Retrieve all floors."""
+ """Retrieve rooms."""
query = (
select(Room)
.options(selectinload(Room.group))
diff --git a/museum_map/server/frontend/src/routes/Floor.svelte b/museum_map/server/frontend/src/routes/Floor.svelte
index bfd564d..9699b92 100644
--- a/museum_map/server/frontend/src/routes/Floor.svelte
+++ b/museum_map/server/frontend/src/routes/Floor.svelte
@@ -9,11 +9,11 @@
import Thumbnail from "../components/Thumbnail.svelte";
import {
floors,
- fetchRooms,
- busyCounter,
+ floorTopics,
+ currentFloor,
+ rooms,
+ currentRooms,
localPreferences,
- loadTopics,
- loadItems,
matchingFloors,
matchingRooms,
tracker,
@@ -41,7 +41,7 @@
class FloorScene extends Phaser.Scene {
floor: Floor;
- roomObjects: MapObject[];
+ roomObjects: MapObject[] = [];
baseMap: Phaser.GameObjects.Image;
zoom: number;
cameraPosition: { x: number; y: number };
@@ -60,7 +60,7 @@
this.zoom = 1;
this.baseMap = this.add.image(0, 0, "basemap");
this.baseMap.setOrigin(0, 0);
- loadRooms(this.floor.rooms).then((rooms) => {
+ /*loadRooms(this.floor.rooms).then((rooms) => {
busyCounter.start();
$matchingRooms = get(matchingRooms);
for (let room of rooms) {
@@ -126,7 +126,7 @@
}
this.scaleObjects(false, false);
busyCounter.stop();
- });
+ });*/
this.cameraPosition = {
x: -this.game.canvas.width / 2 + this.baseMap.width / 2,
@@ -393,6 +393,7 @@
let game: Phaser.Game | null = null;
+ /*
const currentFloor = derived(
[location, floors],
([location, floors]) => {
@@ -409,12 +410,12 @@
return null;
},
null
- );
+ );*/
const previousFloor = derived(
[currentFloor, floors],
([currentFloor, floors]) => {
- if (currentFloor) {
+ if (currentFloor && floors) {
let previousFloor = null;
for (const floor of floors) {
if (floor === currentFloor) {
@@ -431,7 +432,7 @@
const nextFloor = derived(
[currentFloor, floors],
([currentFloor, floors]) => {
- if (currentFloor) {
+ if (currentFloor && floors) {
let found = false;
for (const floor of floors) {
if (found) {
@@ -447,9 +448,65 @@
}
}
);
+ // The floor topics as a floor.id -> topic dictionary
+ const topicsDict = derived(
+ floorTopics,
+ (floorTopics) => {
+ if (floorTopics) {
+ tick().then(() => {
+ if (floorListElement) {
+ const currentElement = floorListElement.querySelector(
+ ".current-floor"
+ ) as HTMLElement;
+ if (currentElement) {
+ currentElement.scrollIntoView();
+ }
+ }
+ });
+
+ const topicsDict: { [x: number]: FloorTopic[] } = {};
+ for (let floorTopic of floorTopics) {
+ if (topicsDict[floorTopic.floor]) {
+ topicsDict[floorTopic.floor].push(floorTopic);
+ } else {
+ topicsDict[floorTopic.floor] = [floorTopic];
+ }
+ }
+ return topicsDict;
+ }
+ return {};
+ },
+ {}
+ );
+
+ const searchedFloors = derived(
+ [floors, matchingFloors],
+ ([floors, matchingFloors]) => {
+ if (floors) {
+ return floors.map((floor) => {
+ return [floor, false];
+ });
+ }
+ return [];
+ },
+ []
+ );
+
+ const searchedRooms = derived(
+ [currentRooms, matchingRooms],
+ ([currentRooms, matchingRooms]) => {
+ if (currentRooms) {
+ return currentRooms.map((room) => {
+ return [room, false];
+ });
+ }
+ return [];
+ },
+ []
+ );
const currentFloorUnsubscribe = currentFloor.subscribe((currentFloor) => {
- if (currentFloor && game) {
+ /*if (currentFloor && game) {
if (!game.scene.getScene("floor-" + currentFloor.id)) {
game.scene.add(
"floor-" + currentFloor.id,
@@ -479,7 +536,7 @@
}
});
}
- }
+ }*/
});
const matchingRoomsUnsubscribe = matchingRooms.subscribe((matchingRooms) => {
@@ -498,83 +555,6 @@
}
});
- const rooms = derived(
- currentFloor,
- (currentFloor, set) => {
- if (currentFloor) {
- loadRooms(currentFloor.rooms).then((rooms) => {
- set(rooms);
- });
- } else {
- set([]);
- }
- },
- [] as Room[]
- );
-
- const topics = derived(
- floors,
- (floors, set) => {
- if (floors) {
- let topicIds = [] as string[];
- for (const floor of floors) {
- topicIds = topicIds.concat(
- (floor.relationships.topics.data as JsonApiObjectReference[]).map(
- (rel) => {
- return rel.id;
- }
- )
- );
- }
- loadTopics(topicIds).then((topics) => {
- const topicsMap = {} as { [x: string]: JsonApiObject[] };
- for (const floor of floors) {
- topicIds = (
- floor.relationships.topics.data as JsonApiObjectReference[]
- ).map((rel) => {
- return rel.id;
- });
- topicsMap[floor.id] = topics.filter((topic) => {
- return topicIds.indexOf(topic.id) >= 0;
- });
- }
- set(topicsMap);
- if (floorListElement) {
- tick().then(() => {
- const currentElement = floorListElement.querySelector(
- ".current-floor"
- ) as HTMLElement;
- if (currentElement) {
- currentElement.scrollIntoView();
- }
- });
- }
- });
- }
- },
- {} as { [x: string]: JsonApiObject[] }
- );
-
- const searchedFloors = derived(
- [floors, matchingFloors],
- ([floors, matchingFloors]) => {
- return floors.map((floor: JsonApiObject) => {
- return [floor, matchingFloors.indexOf(floor.id) >= 0];
- });
- },
- [] as [JsonApiObject, boolean][]
- );
-
- const searchedRooms = derived(
- [rooms, matchingRooms],
- ([rooms, matchingRooms]) => {
- return rooms.map((room) => {
- return [room, matchingRooms.indexOf(room.id) >= 0];
- });
- },
- [] as [JsonApiObject, boolean][]
- );
-
onMount(() => {
document.body.addEventListener("mousemove", (ev: MouseEvent) => {
mousePosition.x = ev.pageX;
@@ -609,10 +589,10 @@
{
tracker.log({
action: "mouseenter",
- params: { object: "previous-floor", floor: $previousFloor.id },
+ params: { object: "previous-floor", floor: $previousFloor?.id },
});
}}
on:mouseleave={() => {
tracker.log({
action: "mouseleave",
- params: { object: "previous-floor", floor: $previousFloor.id },
+ params: { object: "previous-floor", floor: $previousFloor?.id },
});
}}
on:focus={() => {
tracker.log({
action: "focus",
- params: { object: "previous-floor", floor: $previousFloor.id },
+ params: { object: "previous-floor", floor: $previousFloor?.id },
});
}}
on:blur={() => {
tracker.log({
action: "blur",
- params: { object: "previous-floor", floor: $previousFloor.id },
+ params: { object: "previous-floor", floor: $previousFloor?.id },
});
- }}>⇧ {$previousFloor.attributes.label}⇧ {$previousFloor.label}
{:else}
@@ -704,7 +684,7 @@
{
@@ -745,17 +725,17 @@
}}
>
⇒ {floor.attributes.label}⇒ {floor.label}
- {#if $topics[floor.id]}
- {#each $topics[floor.id] as topic}
+ {#if $topicsDict[floor.id]}
+ {#each $topicsDict[floor.id] as topic}
{topic.attributes.label}{topic.label}
{/each}
{/if}
@@ -819,7 +799,7 @@
- {$hoverRoom.attributes.label}
+ {$hoverRoom.label}