All checks were successful
Test Asgard Runner / test (push) Successful in 2s
- DB migrations 017 (betterchat_configs) and 020 (timedexecute_configs) applied - TypeORM entities matching production schema exactly - NestJS modules with full CRUD + apply-to-server + import-from-server - Pinia stores following teleport config pattern - BetterChatView: Chat Groups editor with color pickers, font sizes, format strings; Settings tab with word filter, anti-flood, player tagging - TimedExecuteView: TimerRepeat with presets, RealTime-Timer, OnConnect/OnDisconnect command lists - Wired into app.module.ts, router, DashboardLayout nav Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
146 lines
3.9 KiB
TypeScript
146 lines
3.9 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import { useApi } from '@/composables/useApi'
|
|
import { useToastStore } from '@/stores/toast'
|
|
import type { TimedExecuteConfigSummary, TimedExecuteConfigFull, TimedExecuteApplyResult } from '@/types'
|
|
|
|
export const useTimedExecuteStore = defineStore('timedexecute', () => {
|
|
const configs = ref<TimedExecuteConfigSummary[]>([])
|
|
const currentConfig = ref<TimedExecuteConfigFull | null>(null)
|
|
const isLoading = ref(false)
|
|
const isSaving = ref(false)
|
|
const isApplying = ref(false)
|
|
const isDirty = ref(false)
|
|
const api = useApi()
|
|
const toast = useToastStore()
|
|
|
|
async function fetchConfigs() {
|
|
isLoading.value = true
|
|
try {
|
|
const res = await api.get<{ configs: TimedExecuteConfigSummary[] }>('/timedexecute/configs')
|
|
configs.value = res.configs
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function loadConfig(id: string) {
|
|
isLoading.value = true
|
|
try {
|
|
const res = await api.get<{ config: TimedExecuteConfigFull }>(`/timedexecute/configs/${id}`)
|
|
currentConfig.value = res.config
|
|
isDirty.value = false
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function createConfig(name: string, description?: string) {
|
|
try {
|
|
const res = await api.post<{ config: TimedExecuteConfigFull }>('/timedexecute/configs', {
|
|
config_name: name,
|
|
description,
|
|
})
|
|
await fetchConfigs()
|
|
currentConfig.value = res.config
|
|
isDirty.value = false
|
|
toast.success(`Config "${name}" created`)
|
|
return res.config
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
return null
|
|
}
|
|
}
|
|
|
|
async function saveCurrentConfig() {
|
|
if (!currentConfig.value) return
|
|
isSaving.value = true
|
|
try {
|
|
await api.put(`/timedexecute/configs/${currentConfig.value.id}`, {
|
|
config_name: currentConfig.value.config_name,
|
|
description: currentConfig.value.description,
|
|
config_data: currentConfig.value.config_data,
|
|
})
|
|
isDirty.value = false
|
|
await fetchConfigs()
|
|
toast.success('Config saved')
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
} finally {
|
|
isSaving.value = false
|
|
}
|
|
}
|
|
|
|
async function deleteConfig(id: string) {
|
|
try {
|
|
await api.del(`/timedexecute/configs/${id}`)
|
|
if (currentConfig.value?.id === id) {
|
|
currentConfig.value = null
|
|
}
|
|
await fetchConfigs()
|
|
toast.success('Config deleted')
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
}
|
|
}
|
|
|
|
async function applyToServer(id: string) {
|
|
isApplying.value = true
|
|
try {
|
|
const res = await api.post<TimedExecuteApplyResult>(`/timedexecute/configs/${id}/apply`)
|
|
await fetchConfigs()
|
|
toast.success(res.message)
|
|
return res
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
return null
|
|
} finally {
|
|
isApplying.value = false
|
|
}
|
|
}
|
|
|
|
async function importFromServer(configName: string) {
|
|
isLoading.value = true
|
|
try {
|
|
const res = await api.post<{ config: TimedExecuteConfigFull }>('/timedexecute/import-from-server', {
|
|
config_name: configName,
|
|
})
|
|
await fetchConfigs()
|
|
currentConfig.value = res.config
|
|
isDirty.value = false
|
|
toast.success(`Config imported from server as "${configName}"`)
|
|
return res.config
|
|
} catch (err) {
|
|
toast.error((err as Error).message)
|
|
return null
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
function markDirty() {
|
|
isDirty.value = true
|
|
}
|
|
|
|
return {
|
|
configs,
|
|
currentConfig,
|
|
isLoading,
|
|
isSaving,
|
|
isApplying,
|
|
isDirty,
|
|
fetchConfigs,
|
|
loadConfig,
|
|
createConfig,
|
|
saveCurrentConfig,
|
|
deleteConfig,
|
|
applyToServer,
|
|
importFromServer,
|
|
markDirty,
|
|
}
|
|
})
|