homemanager-fe/src/store/building.store.ts

166 lines
4.8 KiB
TypeScript

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<FloorListItem>
) {
const { data: saveData } = await jfetch<FloorListItem>(
`${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<UpsertRoomItem> {
const canvasId = room.canvasObjectId;
const { data: returned } = await jfetch<RoomListItem>(
`${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<UpsertRoomItem> {
const canvasId = room.canvasObjectId;
const roomId = room.id;
const { data: returned } = await jfetch<RoomListItem>(
`${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<RoomListItem>(
`${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;
},
},
});