better code: restricted scope of 'changes' to config page

Massimo Melina committed Jun 5, 2022 at 11:00 UTC 0819fccdca67624fab1b9d66053854b31804fe8d
2 files changed +15 -14
admin/src/ConfigPage.ts
+15 -12
@@ -12,9 +12,13 @@ import FileField from './FileField'
12 import { alertDialog, closeDialog, confirmDialog, formDialog, newDialog, toast, waitDialog } from './dialog'
13 import { proxyWarning } from './HomePage'
14 import _ from 'lodash';
15 +import { proxy, useSnapshot } from 'valtio'
16
17 let loaded: Dict | undefined
18 let exposedReloadStatus: undefined | (() => void)
19 +const pageState = proxy({
20 + changes: {} as Dict
21 +})
22
23 subscribeKey(state, 'config', recalculateChanges)
24
@@ -26,6 +30,7 @@ export const logLabels = {
30 export default function ConfigPage() {
31 const { data, reload: reloadConfig, element } = useApiEx('get_config', { omit: ['vfs'] })
32 let snap = useSnapState()
33 + const { changes } = useSnapshot(pageState)
34 const statusApi = useApiEx(data && 'get_status')
35 const status = statusApi.data
36 const reloadStatus = exposedReloadStatus = statusApi.reload
@@ -38,7 +43,6 @@ export default function ConfigPage() {
43 return element
44 if (statusApi.error)
45 return statusApi.element
41 - const { changes } = snap
46 const values = (loaded !== data) ? (state.config = loaded = data) : snap.config
47 const maxSpeedDefaults = {
48 comp: NumberField,
@@ -66,7 +70,7 @@ export default function ConfigPage() {
70 startIcon: h(Refresh),
71 }, "Reload")],
72 defaults({ comp }) {
69 - return comp === ServerPort ? { sm: 6, lg: 3 }
73 + return comp === ServerPort ? { sm: 6, md: 3 }
74 : comp === NumberField ? { sm: 3 }
75 : { sm: 6 }
76 },
@@ -123,36 +127,35 @@ export default function ConfigPage() {
127 })
128
129 async function save() {
126 - const values = state.changes
127 - if (_.isEmpty(values))
130 + if (_.isEmpty(changes))
131 return toast("Nothing to save")
132 const loc = window.location
130 - const newPort = loc.protocol === 'http:' ? values.port : values.https_port
133 + const newPort = loc.protocol === 'http:' ? changes.port : changes.https_port
134 if (newPort <= 0 && !await confirmDialog("You are switching off the server port and you will be disconnected"))
135 return
136 else if (newPort > 0 && !await confirmDialog("You are changing the port and you may be disconnected"))
137 return
135 - if (loc.protocol === 'https:' && ('cert' in values || 'private_key' in values) && !await confirmDialog("You may disrupt https service, kicking you out"))
138 + if (loc.protocol === 'https:' && ('cert' in changes || 'private_key' in changes) && !await confirmDialog("You may disrupt https service, kicking you out"))
139 return
137 - await apiCall('set_config', { values })
140 + await apiCall('set_config', { values: changes })
141 if (newPort > 0) {
142 await alertDialog("You are being redirected but in some cases this may fail. Hold on tight!", 'warning')
143 return window.location.href = loc.protocol + '//' + loc.hostname + ':' + newPort + loc.pathname
144 }
142 - setTimeout(reloadStatus, 'port' in values || 'https_port' in values ? 1000 : 0) // give some time to consider new ports
143 - Object.assign(loaded, values) // since changes are recalculated subscribing state.config, but it depends on 'loaded' to (which cannot be subscribed), be sure to update loaded first
145 + setTimeout(reloadStatus, 'port' in changes || 'https_port' in changes ? 1000 : 0) // give some time to consider new ports
146 + Object.assign(loaded, changes) // since changes are recalculated subscribing state.config, but it depends on 'loaded' to (which cannot be subscribed), be sure to update loaded first
147 recalculateChanges()
148 toast("Changes applied", 'success')
149 }
150 }
151
152 function recalculateChanges() {
150 - const changes: Dict = {}
153 + const o: Dict = {}
154 if (state.config)
155 for (const [k, v] of Object.entries(state.config))
156 if (JSON.stringify(v) !== JSON.stringify(loaded?.[k]))
154 - changes[k] = v
155 - state.changes = changes
157 + o[k] = v
158 + pageState.changes = o
159 }
160
161 export function isCertError(error: any) {
admin/src/state.ts
-2
@@ -10,7 +10,6 @@ const STORAGE_KEY = 'admin_state'
10 export const state = proxy<{
11 title: string
12 config: Dict
13 - changes: Dict
13 vfs: VfsNode | undefined
14 selectedFiles: VfsNode[]
15 loginRequired: boolean
@@ -19,7 +18,6 @@ export const state = proxy<{
18 }>(Object.assign({
19 title: '',
20 config: {},
22 - changes: {},
21 selectedFiles: [],
22 vfs: undefined,
23 loginRequired: false,