Delete/Clear Rooms Button on the Dashboard
Is your feature request related to a problem? Please describe.
I have 255 rooms built during development on the production site. I want to be able to clear them all with the click of a button. Could you guys please incorporate that into the dashboard so that it's easier to do? It would mean a lot : )
Describe the solution you'd like
A button to remove all rooms.
Additional context
This is how my dashboard looks like :'D
We can add a "Select All" button to bulk delete all the rooms. Should I go ahead and try this?
That would be great! I'm running into the same issue during development and would love a way to easily clear all rooms.
Oh btw if anyone does want to use this functionality, the following snippet will do wonders:
This is the fetch-all-rooms.ts file:
type FetchRoomFilters = {
isDrawingCompleted?: MetadataBooleanStatusKey | null;
isLive?: MetadataBooleanStatusKey | null;
isPopular?: MetadataBooleanStatusKey | null;
isRecentlyCompleted?: MetadataBooleanStatusKey | null;
};
/**
* This will continuously ping liveblocks for more rooms' data until liveblocks declares that these are indeed all the records in the db.
* It will either fetch rooms marked according to the provided metadata keys.
* */
export const fetchAllRooms = async ({
isDrawingCompleted = null,
isLive = null,
isPopular = null,
isRecentlyCompleted = null,
}: FetchRoomFilters = {}): Promise<RoomData[]> => {
let isLastPage = false;
let nextCursor: NextCursor = null;
const allRooms: RoomData[] = [];
try {
while (!isLastPage) {
const queryMetadata = buildMetadataQuery({
isDrawingCompleted,
isLive,
isPopular,
isRecentlyCompleted,
});
const getRoomParams: GetRoomParams = {
limit: 100,
query: {
/** This roomId is referenced in our codebase as the room identifier or the room name */
roomId: { startsWith: ROOM_NAME_PREFIX },
metadata: queryMetadata,
},
...(nextCursor && { startingAfter: nextCursor }),
};
const { data: rooms, nextCursor: newCursor } = await liveblocks.getRooms(getRoomParams);
allRooms.push(...rooms);
nextCursor = newCursor;
isLastPage = !newCursor;
}
return allRooms;
} catch (error) {
console.error("Error fetching rooms:", error);
return [];
}
};
// Helper to build metadata query object
const buildMetadataQuery = (filters: FetchRoomFilters) => {
const metadataQuery: Record<string, MetadataBooleanStatusKey> = {};
for (const [key, value] of Object.entries(filters)) {
if (value !== null && value !== undefined) {
metadataQuery[key] = value;
}
}
return metadataQuery;
};
And then, in a DELETE endpoint, we can just use these:
// Step 1 -- get all the incomplete rooms
const totalRooms = await fetchAllRooms()
// Step 2 -- store their IDs in a list
const filteredRoomsIds = totalRooms.map(room => room.id)
// Step 3 -- delete all filtered rooms concurrently
await Promise.all(
filteredRoomsIds.map((roomId) => liveblocks.deleteRoom(roomId))
);
Using the latest @liveblocks/node, you can do it with this snippet:
import { Liveblocks } from "./index";
const liveblocks = new Liveblocks({ secret: "sk_xxx" });
for await (const room of liveblocks.iterRooms({/* filter criteria here */})) {
await liveblocks.deleteRoom(room.id);
}