SeatManager from @seatlayer/vue/manager puts the live control room inside
your Vue 3 app. It is a thin layer over the
SeatManager class in @seatlayer/js/manager: the
same board, the same tools, the same token rules. This page covers what is
different in Vue. Read the control-room guide
for the board itself.
Available from @seatlayer/vue 0.106.0.
Import it from the manager entry
import { SeatManager } from "@seatlayer/vue/manager";SeatManager is not exported from the package root. The /manager entry holds
the control room and nothing else, so a buyer page that imports
@seatlayer/vue stays the same size, and a control room does not carry the
buyer picker.
Mount the board
Your backend mints a short-lived, event-scoped mse_ token after it checks
that the signed-in user may manage the event. Never put an sk_ secret key in
browser code. Keep the token in memory, never in a URL, browser storage, or
logs.
<script setup lang="ts">
import { ref } from "vue";
import {
SeatManager,
type SeatManagerExposed,
type SeatManagerRoomState,
} from "@seatlayer/vue/manager";
const props = defineProps<{ session: { token: `mse_${string}`; expiresAt: number } }>();
const manager = ref<SeatManagerExposed | null>(null);
async function mintManageSession() {
const next = await fetch("/api/events/<YOUR_EVENT_KEY>/manage-session", {
method: "POST",
}).then((response) => response.json());
return { token: next.token, expiresAt: next.expiresAt };
}
function onRoomState(state: SeatManagerRoomState) {
console.log("room is", state);
}
function showOperatorError(error: unknown) {
console.error(error);
}
</script>
<template>
<SeatManager
ref="manager"
event-key="<YOUR_EVENT_KEY>"
:token="props.session.token"
:token-expires-at="props.session.expiresAt"
:on-token-refresh="mintManageSession"
style="width: 100%; height: calc(100vh - 96px)"
@room-state-change="onRoomState"
@error="showOperatorError"
/>
</template>Give the component a real height. The board fills its box. It is destroyed when the component unmounts.
Props
The props are the constructor options
without container. Live props change the running board in place: the
camera, selection, live connection and DOM stay. Read once props are read
when the board is built. Changing eventKey or apiBase builds a new board.
| Prop | When it applies |
|---|---|
eventKey, apiBase |
Changing either builds a new board |
token, tokenExpiresAt |
Live |
onTokenRefresh |
Live |
capabilities |
Live |
currency |
Live |
theme |
Live |
themeMode |
Applied before the first paint, then live |
keepLiveWhileHidden |
Live |
mode |
Live |
followLive |
Live |
selectableObjects, unavailableObjectsSelectable |
Live |
unavailableObjects, unavailableObjectsReason |
Live |
categoryPrices |
Live |
maxSelectedObjects, numberOfPlacesToSelect |
Live |
isObjectSelectable |
Live |
sale |
Live, compared by value |
mapInsets |
Live, compared by value |
tools, chrome |
Read once |
selectedObjects |
Read once |
kpis |
Read once. false when your own header shows the numbers |
timeZone |
Read once |
organizationName |
Read once |
colourBy |
Read once |
focusSection, focusSeat, focusSeats, focusCategory |
Read once |
arrivedFrom |
Read once |
onOpenOrder, onOpenTrend |
Read once. See below |
onOpenDesigner |
Read once. When set, Sections on a chart without sections offers “Open the designer” |
“Compared by value” means a new object with the same fields does nothing. You
can build sale or mapInsets inline in a template without repainting the
board on every render.
Events
Each reporting callback is a Vue event.
| Event | Payload |
|---|---|
@ready |
none |
@tallies |
SeatManagerTallies |
@activity |
SeatManagerActivity |
@control-room |
ControlRoomSnapshot |
@mode-change |
SeatManagerMode |
@follow-live-change |
boolean |
@selection-change |
ExpandedSeat[] |
@object-selected, @object-deselected |
ExpandedSeat |
@selection-validity-change, @selection-valid, @selection-invalid |
SeatManagerSelectionValidity |
@selection-limit |
number |
@filtered-section-change |
SeatManagerFilteredSection[] |
@area-click |
SeatManagerArea |
@action-complete |
SeatManagerActionResult |
@connection-change |
SeatManagerConnection |
@room-state-change |
SeatManagerRoomState: connecting, live, paused, offline or ended |
@error |
unknown |
Callbacks that are props
Three callbacks are props, not events:
onTokenRefreshreturns the new token, so it has to be a function the board can call.onOpenOrderandonOpenTrendtell the board you can open an order or a trend view. The board offers “Open order” and the trend link only when you pass one, so it never shows a link that goes nowhere.
Vue sends @open-order="fn" to the onOpenOrder prop, so you can write
either :on-open-order="fn" or @open-order="fn". The same goes for
@open-trend and @token-refresh.
Template ref
The template ref is typed SeatManagerExposed (also exported as
SeatManagerHandle). It has the same methods as the React handle:
| Method | Result |
|---|---|
setMode(mode) |
Switch tool |
setToken(token, expiresAt?) |
Rotate the token without a rebuild |
setHeatOverlay(enabled), setFollowLive(enabled) |
Toggle the overlay or camera following |
setTrendWindow(minutes) |
Refresh and return the control-room snapshot |
enterFullscreen(), exitFullscreen(), isFullscreen() |
Fullscreen |
block(labels?, { releaseAt?, reason? }), unblock(labels?), unblockAll() |
Block or unblock inventory |
cancelBooking(labels, bookingRef) |
Cancel by booking reference |
setCategory(categoryKey, labels?), setTableBooking(tableIds, mode, bounds?) |
Event-only category and table changes |
selectAll(), selectSection(id), selectByLabels(labels) |
Select seats |
selectObjects(labels), deselectObjects(labels) |
Custom selection by label |
selectCategories(keys), deselectCategories(keys) |
Custom selection by category |
setSelectableObjects, setUnavailableObjectsSelectable, setUnavailableObjects, setCategoryPrices, setObjectSelectable, setMaxSelectedObjects, setNumberOfPlacesToSelect |
The live props, called directly |
getSelectionValidity() |
Exact-count state, or null |
setFilteredSection(label), clearFilteredSection(), getFilteredSections() |
Section filter |
focusSection(label) |
Frame matching sections without filtering |
clearSelection(), getSelection() |
Selection |
getReport(), getControlRoomSnapshot(minutes?), getLog({ limit?, before? }) |
Reports and audit log |
setHoldTtl(msOrNull) |
Set or clear the event checkout window |
getConnection() |
Live link state, or null before the board exists |
zoomToFit() |
Fit the chart |
showObjects(labels, name?) |
Light and frame these seats, named in the legend. null clears |
A method called before the board exists returns an empty answer.
getReport, getControlRoomSnapshot and setTrendWindow reject with
not ready.
Types
@seatlayer/vue/manager exports SeatManagerExposed, SeatManagerHandle,
SeatManagerProps, SeatManagerOptions, SeatManagerMode,
EventScopedManageToken, SeatManagerTallies, SeatManagerSale,
SeatManagerActivity, SeatManagerActionResult, SeatManagerConnection,
SeatManagerRoomState, SeatManagerFilteredSection,
SeatManagerSelectionValidity, SeatManagerCategoryPrice,
EventTableBookingMode, ControlRoomActivityEntry,
ControlRoomSectionMetric and ControlRoomSnapshot.
Continue to the SeatManager reference, the control-room guide, and embed sessions.