import omit from 'lodash.omit'; import { defineStore } from 'pinia'; import { useAccessToken } from '../composables/useAccessToken'; import { BACKEND_URL } from '../constants'; import { BuildingListItem, BuildingResponse, } from '../interfaces/building.interfaces'; import { FloorListItem } from '../interfaces/floor.interfaces'; import { RoomListItem, UpsertRoomItem } from '../interfaces/room.interfaces'; import jfetch from '../utils/jfetch'; const { authHeader } = useAccessToken(); export const useBuildingStore = defineStore('building', { state: () => { return { loadingBuildings: false, buildings: [] as BuildingListItem[], loadingFloors: false, floors: [] as FloorListItem[], building: null as null | BuildingResponse, }; }, actions: { async getBuilding(id: number) { const { data: building } = await jfetch( `${BACKEND_URL}/buildings/${id}`, { headers: authHeader.value, } ); this.building = building; }, async getBuildings() { this.loadingBuildings = true; try { const { data: buildings } = await jfetch(`${BACKEND_URL}/buildings`, { headers: authHeader.value, }); this.buildings = buildings; } finally { this.loadingBuildings = false; } }, async getFloors(building: number) { this.loadingFloors = true; try { const { data: floors } = await jfetch( `${BACKEND_URL}/buildings/${building}/floors`, { headers: authHeader.value, } ); this.floors = floors; } finally { this.loadingFloors = false; } }, async saveFloor( building: number, number: number, floor: Partial ) { const { data: saveData } = await jfetch( `${BACKEND_URL}/buildings/${building}/floors/${number}`, { method: 'PATCH', headers: authHeader.value, body: floor, } ); // Update local state const currentFloor = this.floors.find( (existing) => existing.number === number ); if (currentFloor) { Object.assign(currentFloor, saveData); } return saveData; }, async createRoom( building: number, floor: number, room: UpsertRoomItem ): Promise { const canvasId = room.canvasObjectId; const { data: returned } = await jfetch( `${BACKEND_URL}/buildings/${building}/floors/${floor}/rooms`, { method: 'POST', headers: authHeader.value, body: omit(room, 'canvasObjectId'), } ); return { ...returned, canvasObjectId: canvasId }; }, async updateRoom( building: number, room: UpsertRoomItem ): Promise { const canvasId = room.canvasObjectId; const roomId = room.id; const { data: returned } = await jfetch( `${BACKEND_URL}/buildings/${building}/rooms/${roomId}`, { method: 'PATCH', headers: authHeader.value, body: omit(room, ['canvasObjectId', 'id']), } ); return { ...returned, canvasObjectId: canvasId }; }, async deleteRoom(building: number, roomId: number) { await jfetch( `${BACKEND_URL}/buildings/${building}/rooms/${roomId}`, { method: 'DELETE', headers: authHeader.value, } ); }, async upsertFloorRooms( building: number, floorNo: number, rooms: UpsertRoomItem[] ) { const currentBuilding = this.buildings.find(({ id }) => building === id); const currentFloor = this.floors.find(({ number }) => number === floorNo); if (!currentBuilding || !currentFloor) return; // Gather data const roomsToCreate = rooms.filter( (room) => room.id === undefined && room.displayName && room.plan ); const roomsToUpdate = rooms.filter((room) => { if (!room.id) return false; const exists = currentFloor.rooms.find( (existing) => existing.id === room.id ); if (!exists) return false; return ( exists.displayName !== room.displayName || exists.plan !== room.plan ); }); const roomsToDelete = currentFloor.rooms.filter( (room) => !rooms.find((provided) => provided.id === room.id) ); // Do requests const createdRooms = await Promise.all( roomsToCreate.map((room) => this.createRoom(building, floorNo, room)) ); await Promise.allSettled( roomsToUpdate.map((room) => this.updateRoom(building, room)) ); await Promise.allSettled( roomsToDelete.map((room) => this.deleteRoom(building, room.id)) ); return createdRooms; }, }, });