refactor(frontend): extract shared fmtSize, remove duplicate ModEntry, use shared ConfigEditor
- Extract fmtSize to src/utils/format.ts (was duplicated in Mods.tsx and Status.tsx) - Remove duplicate ModEntry interface from ModlistEditor.tsx, import from types - Refactor pages/ConfigEditor.tsx to use shared components/ConfigEditor.tsx - Add enabled option to queries with undefined params to prevent premature fetches
This commit is contained in:
@@ -2,12 +2,16 @@ import { useParams, Link } from 'react-router-dom'
|
|||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||||
import { configsApi } from '../api/client'
|
import { configsApi } from '../api/client'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import Editor from '@monaco-editor/react'
|
import ConfigEditorComponent from '../components/ConfigEditor'
|
||||||
|
|
||||||
export default function ConfigEditor() {
|
export default function ConfigEditor() {
|
||||||
const { name } = useParams<{ name: string }>()
|
const { name } = useParams<{ name: string }>()
|
||||||
const qc = useQueryClient()
|
const qc = useQueryClient()
|
||||||
const { data: content, isLoading } = useQuery({ queryKey: ['config', name], queryFn: () => configsApi.get(name!) })
|
const { data: content, isLoading } = useQuery({
|
||||||
|
queryKey: ['config', name],
|
||||||
|
queryFn: () => configsApi.get(name!),
|
||||||
|
enabled: !!name,
|
||||||
|
})
|
||||||
const [value, setValue] = useState('')
|
const [value, setValue] = useState('')
|
||||||
const [dirty, setDirty] = useState(false)
|
const [dirty, setDirty] = useState(false)
|
||||||
|
|
||||||
@@ -18,8 +22,8 @@ export default function ConfigEditor() {
|
|||||||
onSuccess: () => { qc.invalidateQueries({ queryKey: ['config', name] }); setDirty(false) },
|
onSuccess: () => { qc.invalidateQueries({ queryKey: ['config', name] }); setDirty(false) },
|
||||||
})
|
})
|
||||||
|
|
||||||
if (isLoading) return <p className="text-neutral-500">Loading...</p>
|
|
||||||
if (!name) return <p className="text-red-400">No config specified</p>
|
if (!name) return <p className="text-red-400">No config specified</p>
|
||||||
|
if (isLoading) return <p className="text-neutral-500">Loading...</p>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -33,24 +37,10 @@ export default function ConfigEditor() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="border border-neutral-800 rounded-lg overflow-hidden">
|
<ConfigEditorComponent
|
||||||
<Editor
|
|
||||||
height="600px"
|
|
||||||
language="plaintext"
|
|
||||||
value={value}
|
value={value}
|
||||||
onChange={v => { setValue(v ?? ''); setDirty(true) }}
|
onChange={v => { setValue(v); setDirty(true) }}
|
||||||
theme="vs-dark"
|
|
||||||
options={{
|
|
||||||
minimap: { enabled: false },
|
|
||||||
fontSize: 13,
|
|
||||||
fontFamily: '"JetBrains Mono", "Fira Code", monospace',
|
|
||||||
lineNumbers: 'on',
|
|
||||||
scrollBeyondLastLine: false,
|
|
||||||
automaticLayout: true,
|
|
||||||
tabSize: 2,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,16 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|||||||
import { modlistsApi, steamcmdApi, logsApi } from '../api/client'
|
import { modlistsApi, steamcmdApi, logsApi } from '../api/client'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import LiveTerminal from '../components/LiveTerminal'
|
import LiveTerminal from '../components/LiveTerminal'
|
||||||
|
import type { ModEntry } from '../types'
|
||||||
interface ModEntry {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
enabled: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ModlistEditor() {
|
export default function ModlistEditor() {
|
||||||
const { id } = useParams<{ id: string }>()
|
const { id } = useParams<{ id: string }>()
|
||||||
const qc = useQueryClient()
|
const qc = useQueryClient()
|
||||||
const { data: modlist, isLoading } = useQuery({ queryKey: ['modlist', id], queryFn: () => modlistsApi.get(id!) })
|
const { data: modlist, isLoading } = useQuery({
|
||||||
|
queryKey: ['modlist', id],
|
||||||
|
queryFn: () => modlistsApi.get(id!),
|
||||||
|
enabled: !!id,
|
||||||
|
})
|
||||||
const [name, setName] = useState('')
|
const [name, setName] = useState('')
|
||||||
const [mods, setMods] = useState<ModEntry[]>([])
|
const [mods, setMods] = useState<ModEntry[]>([])
|
||||||
const [dirty, setDirty] = useState(false)
|
const [dirty, setDirty] = useState(false)
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||||
import { modsApi } from '../api/client'
|
import { modsApi } from '../api/client'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { fmtSize } from '../utils/format'
|
||||||
function fmtSize(bytes: number): string {
|
|
||||||
if (bytes === 0) return '0 B'
|
|
||||||
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(1024))
|
|
||||||
const v = bytes / Math.pow(1024, i)
|
|
||||||
return `${v.toFixed(i > 0 ? 1 : 0)} ${units[i]}`
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Mods() {
|
export default function Mods() {
|
||||||
const qc = useQueryClient()
|
const qc = useQueryClient()
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { settingsApi } from '../api/client'
|
import { settingsApi } from '../api/client'
|
||||||
|
import { fmtSize } from '../utils/format'
|
||||||
function fmtSize(bytes: number): string {
|
|
||||||
if (bytes === 0) return '0 B'
|
|
||||||
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
||||||
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
|
|
||||||
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + units[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
function fmtPercent(p: number): string {
|
function fmtPercent(p: number): string {
|
||||||
return p.toFixed(1) + '%'
|
return p.toFixed(1) + '%'
|
||||||
|
|||||||
Reference in New Issue
Block a user