I dont even remember
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
<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">
|
||||
@@ -19,7 +22,11 @@
|
||||
|
||||
<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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
13
src/user.ts
13
src/user.ts
@@ -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(() => {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user