@samitouri / QOSami-HFS / commits / 76a4d5df

fix: (regression 0.47.0) admin/fs: masks field was broken

Massimo Melina committed Jul 22, 2023 at 12:27 UTC 76a4d5dfa4216bc683596950014d49628b8945c9
5 files changed +30 -11
admin/src/AccountForm.ts
+1 -1
@@ -28,7 +28,7 @@ export default function AccountForm({ account, done, groups, addToBar, reload }:
28 formRef: ref,
29 values,
30 set(v, k) {
31 - setValues({ ...values, [k]: v })
31 + setValues(values => ({ ...values, [k]: v }))
32 },
33 barSx: { gap: 2, width: '100%', ...useDialogBarColors() },
34 stickyBar: true,
admin/src/FileForm.ts
+5 -3
@@ -81,9 +81,11 @@ export default function FileForm({ file, anyMask, defaultPerms, addToBar, status
81 values,
82 set(v, k) {
83 if (k === 'link') return
84 - const nameIsVirtual = k === 'source' && values.source?.endsWith(values.name)
85 - const name = nameIsVirtual ? basename(v) : values.name // update name if virtual
86 - setValues({ ...values, name, [k]: v })
84 + setValues(values => {
85 + const nameIsVirtual = k === 'source' && values.source?.endsWith(values.name)
86 + const name = nameIsVirtual ? basename(v) : values.name // update name if virtual
87 + return { ...values, name, [k]: v }
88 + })
89 },
90 barSx: { gap: 2, width: '100%', ...barColors },
91 stickyBar: true,
admin/src/LoginRequired.ts
+1 -1
@@ -31,7 +31,7 @@ function LoginForm() {
31 formRef,
32 values,
33 set(v, k) {
34 - setValues({ ...values, [k]: v })
34 + setValues(values => ({ ...values, [k]: v }))
35 },
36 fields: [
37 { k: 'username', autoComplete: 'username', autoFocus: true, required: true },
admin/src/dialog.ts
+5 -3
@@ -172,9 +172,11 @@ export async function formDialog<T>(
172 ...props,
173 values: curValues,
174 set(v, k) {
175 - const newV = { ...curValues, [k]: v }
176 - setCurValues(newV)
177 - onChange?.(newV, { setValues: setCurValues })
175 + setCurValues(curValues => {
176 + const newV = { ...curValues, [k]: v }
177 + onChange?.(newV, { setValues: setCurValues })
178 + return newV
179 + })
180 },
181 save: {
182 ...props.save,
mui-grid-form/StringField.ts
+18 -3
@@ -1,10 +1,11 @@
1 // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 -import { createElement as h, ReactNode, useEffect, useRef, useState } from 'react'
3 +import { createElement as h, ReactNode, useCallback, useEffect, useRef, useState } from 'react'
4 import { FieldProps } from '.'
5 import { Autocomplete, InputAdornment, TextField } from '@mui/material'
6 +import { StandardTextFieldProps } from '@mui/material/TextField/TextField'
7
7 -interface StringProps extends FieldProps<string> {
8 +interface StringProps extends FieldProps<string>, Partial<Omit<StandardTextFieldProps, 'label' | 'onChange' | 'value'>> {
9 typing?: boolean
10 onTyping?: (v: string) => boolean
11 min?: number
@@ -25,6 +26,7 @@ export function StringField({ value, onChange, min, max, required, getApi, typin
26 })
27 const [state, setState] = useState(normalized)
28
29 + useProxyRef(props, 'inputRef', useCallback((x: any) => x && go(null, x.value), [])) // support autofill on chrome mobile
30 const lastChange = useRef(normalized)
31 useEffect(() => {
32 setState(normalized)
@@ -36,7 +38,6 @@ export function StringField({ value, onChange, min, max, required, getApi, typin
38 ...props,
39 sx: props.label ? props.sx : Object.assign({ '& .MuiInputBase-input': { pt: 1.5 } }, props.sx),
40 value: state,
39 - onInput(ev: any) { go(ev, ev.target.value) }, // necessary to support autofill on chrome mobile
41 onChange(ev) {
42 const val = ev.target.value
43 if (onTyping?.(val) === false) return
@@ -78,3 +79,17 @@ export function StringField({ value, onChange, min, max, required, getApi, typin
79 }
80 }
81
82 +// intercept a ref prop. Return another Ref, but you can use the callback instead
83 +function useProxyRef(props: any, propName: string, cb?: (instance: any) => void) {
84 + const ret = useRef()
85 + const was = props[propName]
86 + props[propName] = (instance: any) => { // callback is called twice, first time with null. This happens because it is controlled.
87 + ret.current = instance
88 + cb?.(instance)
89 + if (typeof was === 'function')
90 + was(instance)
91 + else if (was)
92 + (was as any).current = instance
93 + }
94 + return ret
95 +}