I dont even remember

This commit is contained in:
iamBadgers
2026-07-18 18:40:58 -07:00
parent b34aa722e4
commit 0ade9df7bc
8 changed files with 156 additions and 155 deletions

View File

@@ -6,7 +6,7 @@ import InputText from 'primevue/inputtext'
import Button from 'primevue/button'
import Card from 'primevue/card'
import Select from 'primevue/select'
import FloatLabel from 'primevue/floatlabel';
import FloatLabel from 'primevue/floatlabel'
const router = useRouter()
const table_name = ref()
@@ -60,7 +60,12 @@ function clear() {
</FloatLabel>
<FloatLabel variant="on">
<Select id="table_version" class="button-box w-full" v-model="version" :options="availableVersion"></Select>
<Select
id="table_version"
class="button-box w-full"
v-model="version"
:options="availableVersion"
></Select>
<label for="table_version">Foundry Version</label>
</FloatLabel>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<Form v-if="!userData.authenticated" v-slot="$form" @submit="onFormSubmit">
<Form v-if="userData === null || !userData.authenticated" v-slot="$form" @submit="onFormSubmit">
<div class="flex flex-column">
<InputText name="username" type="text" placeholder="Username" fluid />
<Password name="password" placeholder="Password" :feedback="false" fluid />
@@ -7,7 +7,7 @@
</div>
</Form>
<div v-if="userData.authenticated">
<div v-if="userData !== null && userData.authenticated">
<div>Logged in as: {{ userData.is_admin ? 'Admin' : '' }} {{ userData.username }}</div>
<Form v-slot="$form" @submit="onResetPassword">
<Password name="password" placeholder="Password" :feedback="false" fluid />

View File

@@ -42,15 +42,14 @@ onMounted(() => {
function tableLink() {
if (!selectedTableRef.value) {
linkVisible.value = false
return ""
return ''
}
linkVisible.value = true
return 'http://' + hostname.value + "/" + selectedTableRef.value.table_link
return 'http://' + hostname.value + '/' + selectedTableRef.value.table_link
}
function displayUsername(): string {
const authenticated = userRef.value.authenticated
if (authenticated) {
if (userRef.value !== null && userRef.value.authenticated) {
return userRef.value.username
}
return 'Login'

View File

@@ -1,19 +1,20 @@
<template>
<ConfirmDialog></ConfirmDialog>
<div class="flex flex-row">
<div class="flex flex-row" v-if="activeTable">
<Card class="detailCard flex">
<template #title>
{{ table.table_name }}
{{ activeTable.table_name }}
</template>
<template #subtitle>
<div>
Status:
<Chip :class="table.active ? 'active' : 'inactive'" :label="table.active ? 'active' : 'inactive'" />
<Chip :class="activeTable.active ? 'active' : 'inactive'"
:label="activeTable.active ? 'active' : 'inactive'" />
</div>
</template>
<template #content>
<div :class="table.active ? 'active-foundry-stats' : 'inactive-foundry-stats'">
<div :class="activeTable.active ? 'active-foundry-stats' : 'inactive-foundry-stats'">
<div>Table Status: {{ foundryStatus.active }}</div>
<div>World: {{ foundryStatus.world }}</div>
<div>Users: {{ foundryStatus.users }}</div>
@@ -21,18 +22,18 @@
</template>
<template #footer>
<div>
<Button class="button-box" label="Start" @click="startTable(activeTable!)" />
<Button class="button-box" label="Stop" @click="stopTable(activeTable!)" />
<Button class="button-box" label="Start" @click="startTable(activeTable)" />
<Button class="button-box" label="Stop" @click="stopTable(activeTable)" />
</div>
<div>
<Button class="button-box" label="Hard Start" @click="hardStartTable(activeTable!)" />
<Button class="button-box" label="Hard Start" @click="hardStartTable(activeTable)" />
<Button class="button-box" label="Delete" @click="protectedDelete()" />
</div>
</template>
</Card>
<Form :key="forceReset" ref="edit-form" :initialValues="activeTable!" @submit="save">
<Card class="detailCard flex">
<Card class="detailCard">
<template #title> Edit Details </template>
<template #content>
<div class="flex flex-column">
@@ -45,8 +46,8 @@
<label>Table Link</label>
</FloatLabel>
<FloatLabel variant="on">
<Select class="button-box" name="version" :options="availableVersion"></Select>
<label>Table Link</label>
<Select class="button-box" name="version" placeholder="11" :options="availableVersion"></Select>
<label>Version</label>
</FloatLabel>
</div>
</template>
@@ -95,9 +96,10 @@ import Card from 'primevue/card'
import Chip from 'primevue/chip'
import Select from 'primevue/select'
import ConfirmDialog from 'primevue/confirmdialog'
import FloatLabel from 'primevue/floatlabel';
import FloatLabel from 'primevue/floatlabel'
import {
getFoundryStatus,
useSelectedTable,
loadSelectedTable,
clearSelectedTable,
@@ -107,8 +109,9 @@ import {
updateTable,
deleteTable,
} from './game_tables'
import { useUserData } from './user'
import type { GameTable } from './game_tables'
import type { GameTable, FoundryStatus } from './game_tables'
import type { Ref } from 'vue'
const hostname = ref()
@@ -116,44 +119,28 @@ const route = useRoute()
const router = useRouter()
const confirm = useConfirm()
const table = reactive({
table_name: 'default',
table_link: 'default',
active: 0,
version: 0,
})
const activeUser = useUserData()
const activeTable: Ref<GameTable | null> = useSelectedTable()
const forceReset = ref(0)
const foundryStatus = reactive({
const foundryStatus: Ref<FoundryStatus> = ref({
running: false,
active: false,
world: '',
users: 0,
})
const currentUser = ref({
username: 'None',
authenticated: 'False',
is_admin: 'False',
})
const availableVersion = ref([11, 12])
var interval: number
onMounted(() => {
interval = setInterval(() => {
readTable()
readFoundryStatus()
}, 2000)
loadTable()
loadSelectedTable(+route.params.id!)
axios.get('/api/auth/user').then((resp) => (currentUser.value = resp.data))
hostname.value = location.host
})
@@ -162,64 +149,34 @@ onUnmounted(() => {
clearSelectedTable()
})
function readTable() {
axios.get(`/api/tables/${route.params.id}`).then((resp) => {
table.table_name = resp.data.table_name
table.table_link = resp.data.table_link
table.active = resp.data.active
})
}
function readFoundryStatus() {
if (activeTable.value) {
axios.get(`http://${activeTable.value.table_link}.${hostname.value}/api/status`).then((resp) => {
if (resp.status == 200) {
foundryStatus.running = resp.data.version
foundryStatus.active = resp.data.active
foundryStatus.world = resp.data.world
foundryStatus.users = resp.data.users
} else {
foundryStatus.running = false
foundryStatus.active = false
foundryStatus.world = 'Not Loaded'
foundryStatus.users = 0
}
})
}
}
watch(activeTable, () => {
forceReset.value++
})
async function readFoundryStatus() {
if (activeTable.value) {
foundryStatus.value = (await getFoundryStatus(activeTable.value)) || {
running: false,
active: false,
world: 'Potato',
users: 0,
}
}
}
function protectedDelete() {
if (activeTable.value) {
confirm.require({
header: `Delete ${table.table_name}?`,
header: `Delete ${activeTable.value.table_name}?`,
message: "This will delete the table and all of it's data",
accept: () => {
deleteTable(activeTable.value!)
deleteTable(activeTable.value)
router.push('/')
},
})
}
}
function loadTable() {
axios
.get(`/api/tables/${route.params.id}`)
.then((resp) => {
table.table_name = resp.data.table_name
table.table_link = resp.data.table_link
table.active = resp.data.active
return axios.get(`/${table.table_link}/api/status`)
})
.then((resp) => {
foundryStatus.active = resp.data.active
foundryStatus.world = resp.data.world
foundryStatus.users = resp.data.users
})
}
function save(form: any) {
if (activeTable.value) {
updateTable(activeTable.value.id, {
@@ -228,20 +185,20 @@ function save(form: any) {
table_link: form.values.table_link,
active: activeTable.value.active,
version: form.values.version,
user_id: activeTable.value.user_id
user_id: activeTable.value.user_id,
})
}
}
function isTableLoading() {
return table.active && !foundryStatus.running
return activeTable.value !== null && activeTable.value.active && !foundryStatus.value.running
}
function isTableInactive() {
return !table.active
return activeTable.value !== null && !activeTable.value.active
}
function isTableReady() {
return table.active && foundryStatus.running
return activeTable.value !== null && activeTable.value.active && foundryStatus.value.running
}
</script>

View File

@@ -8,18 +8,25 @@
<Column field="table_link" header="Table Link">
<template #body="slotProps">
<a v-if="slotProps.data.active" :href="'http://' + hostname + '/' + slotProps.data.table_link"">
<a
v-if="slotProps.data.active"
:href="'http://' + hostname + '/' + slotProps.data.table_link"
>
http://{{ hostname }}/{{ slotProps.data.table_link }}
</a>
<div v-if="!slotProps.data.active">
http://{{ hostname }}/{{ slotProps.data.table_link }}
</div>
</div>
</template>
</Column>
<Column header="Actions" v-if="showClose">
<template #body="slotProps">
<Button label="Close" @click="stopTable(slotProps.data)" :disabled="!isTableOwner(slotProps.data)" />
<Button
label="Close"
@click="stopTable(slotProps.data)"
:disabled="!isTableOwner(slotProps.data)"
/>
</template>
</Column>
@@ -27,8 +34,12 @@
<template #body="slotProps">
<div class="flex flex-row">
<span class="flex"></span>
<SplitButton label="Start" @click="startTable(slotProps.data)" :model="buildButtonModel(slotProps.data)"
:disabled="!isTableOwner(slotProps.data)" />
<SplitButton
label="Start"
@click="startTable(slotProps.data)"
:model="buildButtonModel(slotProps.data)"
:disabled="!isTableOwner(slotProps.data)"
/>
</div>
</template>
</Column>
@@ -49,12 +60,7 @@ import ConfirmDialog from 'primevue/confirmdialog'
import { useConfirm } from 'primevue/useconfirm'
import { useUserData } from './user'
import {
startTable,
hardStartTable,
stopTable,
deleteTable,
} from './game_tables'
import { startTable, hardStartTable, stopTable, deleteTable } from './game_tables'
import type { GameTable } from './game_tables'
@@ -105,6 +111,6 @@ function buildButtonModel(table: any) {
}
function isTableOwner(gameTable: GameTable): boolean {
return user.value.is_admin || gameTable.user_id == user.value.id
return user.value !== null && (user.value.is_admin || gameTable.user_id == user.value.id)
}
</script>

View File

@@ -1,13 +1,29 @@
<script setup lang="ts">
import { useActiveTables, useAllTables } from './game_tables'
<template>
<Card class="ActiveTables">
<template #title>
<h2>Active Tables</h2>
</template>
import TableList from './TableList.vue'
import Button from 'primevue/button'
import Card from 'primevue/card'
<template #content>
<TableList :show-close="true" :game-tables="activeTables" />
</template>
</Card>
const allTables = useAllTables()
const activeTables = useActiveTables()
</script>
<Card class="AllTables">
<template #title>
<h2>All Tables</h2>
</template>
<template #content>
<TableList :show-full-actions="true" :game-tables="allTables" />
<div class="button-box flex justify-content-end">
<router-link to="/new">
<Button :disabled="userData == null" label="New Table" />
</router-link>
</div>
</template>
</Card>
</template>
<style>
@import 'primeflex/primeflex.css';
@@ -42,29 +58,15 @@ const activeTables = useActiveTables()
}
</style>
<template>
<Card class="ActiveTables">
<template #title>
<h2>Active Tables</h2>
</template>
<script setup lang="ts">
import { useActiveTables, useAllTables } from './game_tables'
import { useUserData } from './user'
<template #content>
<TableList :show-close="true" :game-tables="activeTables" />
</template>
</Card>
import TableList from './TableList.vue'
import Button from 'primevue/button'
import Card from 'primevue/card'
<Card class="AllTables">
<template #title>
<h2>All Tables</h2>
</template>
<template #content>
<TableList :show-full-actions="true" :game-tables="allTables" />
<div class="button-box flex justify-content-end">
<router-link to="/new">
<Button label="New Table" />
</router-link>
</div>
</template>
</Card>
</template>
const allTables = useAllTables()
const activeTables = useActiveTables()
const userData = useUserData()
</script>

View File

@@ -11,6 +11,13 @@ export interface GameTable {
user_id: number
}
export interface FoundryStatus {
running: boolean
active: boolean
world: string
users: number
}
let $selectedTable: Ref<GameTable | null> | undefined
let $activeTables: Ref<Array<GameTable>> | undefined
let $allTables: Ref<Array<GameTable>> | undefined
@@ -28,8 +35,7 @@ export function useAllTables(): Ref<Array<GameTable>> {
}
export function useSelectedTable(): Ref<GameTable | null> {
if (!$selectedTable)
$selectedTable = ref(null)
if (!$selectedTable) $selectedTable = ref(null)
return $selectedTable
}
@@ -43,31 +49,35 @@ export function loadAllTables(): void {
}
export function loadSelectedTable(tableId: number = 0): void {
if ($selectedTable && $selectedTable.value) {
let id = tableId || $selectedTable.value.id
axios.get(`/api/tables/${id}`).then((resp) => ($selectedTable!.value = resp.data))
if ($selectedTable && $selectedTable.value && tableId === 0) {
axios
.get(`/api/tables/${$selectedTable.value.id}`)
.then((resp) => ($selectedTable!.value = resp.data))
} else if (tableId !== 0) {
axios.get(`/api/tables/${tableId}`).then((resp) => ($selectedTable!.value = resp.data))
}
}
export function clearSelectedTable(): void {
if ($selectedTable) {
$selectedTable.value = {
id: 0,
table_name: 'None',
table_link: 'None',
active: false,
version: 0,
user_id: 0,
}
$selectedTable.value = null
}
}
export async function startTable(gameTable: GameTable): Promise<void> {
export async function startTable(gameTable: GameTable | null): Promise<void> {
if (gameTable === null) {
return
}
await axios
.post(`/api/tables/${gameTable.id}:start`, { hard: 'False' })
.then(() => loadAllTables())
.then(() => loadActiveTables())
.then(() => loadSelectedTable())
.catch(e => {
console.log(e)
console.log(e.response)
})
for (let retries = 0; retries < 10; retries++) {
try {
@@ -75,10 +85,9 @@ export async function startTable(gameTable: GameTable): Promise<void> {
console.log('loaded')
return
} catch {
await new Promise(f => setTimeout(f, 1000))
await new Promise((f) => setTimeout(f, 1000))
}
}
}
export function hardStartTable(gameTable: GameTable): void {
@@ -114,10 +123,26 @@ export function updateTable(tableId: number, updatedTable: GameTable): void {
.then(() => loadSelectedTable())
}
export function deleteTable(gameTable: GameTable): void {
axios
.delete(`/api/tables/${gameTable.id}`)
.then(() => loadAllTables())
.then(() => loadActiveTables())
.then(() => loadSelectedTable())
export function deleteTable(gameTable: GameTable | null): void {
if (gameTable !== null) {
axios
.delete(`/api/tables/${gameTable.id}`)
.then(() => loadAllTables())
.then(() => loadActiveTables())
.then(() => loadSelectedTable())
}
}
export async function getFoundryStatus(gameTable: GameTable): Promise<FoundryStatus | null> {
return axios.get(`http://${location.host}/${gameTable.table_link}/api/status`).then((resp) => {
if (typeof resp.data !== 'string') {
return {
running: resp.data.version,
active: resp.data.active,
world: resp.data.world,
users: resp.data.users,
}
}
return null
})
}

View File

@@ -9,17 +9,21 @@ export interface User {
authenticated: boolean
}
const $current_user = ref({ id: 0, username: 'username', is_admin: false, authenticated: false })
const $current_user: Ref<User | null> = ref(null)
function loadCurrentUser(): void {
axios.get('/api/auth/user').then((resp) => {
$current_user.value = resp.data
}).catch(() => {
$current_user.value = null
})
}
export function useUserData(): Ref<User> {
export function useUserData(): Ref<User | null> {
onMounted(() => {
loadCurrentUser()
if ($current_user.value === null) {
loadCurrentUser()
}
})
return readonly($current_user)
@@ -32,7 +36,7 @@ export function login(username: string, password: string): void {
}
export function logout(): void {
if ($current_user.value.authenticated) {
if ($current_user.value && $current_user.value.authenticated) {
axios.post('/api/auth/logout').then((resp) => {
$current_user.value = resp.data
})
@@ -40,6 +44,9 @@ export function logout(): void {
}
export function resetPassword(password: string): void {
if ($current_user.value === null) {
return
}
axios.post(`/api/auth/user/${$current_user.value.id}`, {
username: $current_user.value.username,
password,