[verified] refactor: harden operations and redesign device console
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
export function fleetStatusKind(status) {
|
||||
if (!status) return 'unknown'
|
||||
if (!status.reachable) return 'offline'
|
||||
if (status.authenticated === false) return 'auth'
|
||||
return 'online'
|
||||
}
|
||||
|
||||
export function filterAndSortFleet(instances, statuses, { filter = 'all', query = '', sort = 'name' } = {}) {
|
||||
const needle = String(query).trim().toLocaleLowerCase()
|
||||
const rank = { online: 0, auth: 1, offline: 2, unknown: 3 }
|
||||
return instances.filter(item => {
|
||||
const status = statuses.get(item.id)
|
||||
if (filter !== 'all' && fleetStatusKind(status) !== filter) return false
|
||||
if (!needle) return true
|
||||
return [item.id, item.name, item.url, item.description, ...(item.tags || []), JSON.stringify(status?.summary || {})]
|
||||
.join(' ').toLocaleLowerCase().includes(needle)
|
||||
}).slice().sort((a, b) => {
|
||||
const sa = statuses.get(a.id); const sb = statuses.get(b.id)
|
||||
if (sort === 'latency') return (sa?.latencyMs ?? Infinity) - (sb?.latencyMs ?? Infinity) || String(a.name || a.id).localeCompare(String(b.name || b.id))
|
||||
if (sort === 'status') return rank[fleetStatusKind(sa)] - rank[fleetStatusKind(sb)] || String(a.name || a.id).localeCompare(String(b.name || b.id))
|
||||
return String(a.name || a.id).localeCompare(String(b.name || b.id))
|
||||
})
|
||||
}
|
||||
|
||||
export function emptyFleetReason({ total = 0, query = '', filter = 'all', visible = 0 } = {}) {
|
||||
if (!total) return 'config'
|
||||
if (!visible && String(query).trim()) return 'search'
|
||||
if (!visible && filter !== 'all') return 'filter'
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
export function instanceDraftPayload(values, editing = false) {
|
||||
const action = editing ? (values.passwordAction || 'preserve') : (values.passwordAction || (values.password ? 'set' : 'clear'))
|
||||
if (!['preserve', 'set', 'clear'].includes(action)) throw new Error('无效密码操作')
|
||||
if (action === 'set' && !String(values.password || '')) throw new Error('设置密码时必须输入密码')
|
||||
if (action === 'clear' && editing && !values.clearConfirmed) throw new Error('清除密码需要显式确认')
|
||||
const payload = {
|
||||
id: String(values.id || '').trim(), name: String(values.name || '').trim(), url: String(values.url || '').trim(),
|
||||
description: String(values.description || '').trim(), tags: Array.isArray(values.tags) ? values.tags : [], passwordAction: action,
|
||||
}
|
||||
if (action === 'set') payload.password = String(values.password)
|
||||
return payload
|
||||
}
|
||||
|
||||
export function requestDraft(method, path, body) {
|
||||
const normalizedMethod = String(method || 'GET').toUpperCase()
|
||||
const result = { method: normalizedMethod, path: String(path || '') }
|
||||
if (normalizedMethod !== 'GET' && body !== undefined) result.body = body
|
||||
return result
|
||||
}
|
||||
|
||||
export const isWriteMethod = method => ['POST', 'PUT', 'PATCH', 'DELETE'].includes(String(method).toUpperCase())
|
||||
@@ -1,14 +1,19 @@
|
||||
export class RequestCoordinator {
|
||||
#versions = new Map()
|
||||
async run(channel, ownerId, operation) {
|
||||
next(channel) {
|
||||
const version = (this.#versions.get(channel) || 0) + 1
|
||||
this.#versions.set(channel, version)
|
||||
return version
|
||||
}
|
||||
isCurrent(channel, version) { return this.#versions.get(channel) === version }
|
||||
async run(channel, ownerId, operation) {
|
||||
const version = this.next(channel)
|
||||
try {
|
||||
const value = await operation()
|
||||
return { accepted: this.#versions.get(channel) === version, ownerId, value }
|
||||
return { accepted: this.isCurrent(channel, version), ownerId, value }
|
||||
} catch (error) {
|
||||
return { accepted: this.#versions.get(channel) === version, ownerId, error }
|
||||
return { accepted: this.isCurrent(channel, version), ownerId, error }
|
||||
}
|
||||
}
|
||||
invalidate(channel) { this.#versions.set(channel, (this.#versions.get(channel) || 0) + 1) }
|
||||
invalidate(channel) { return this.next(channel) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user