ux: admin/options: clear button for some number fields
Massimo Melina committed
Sep 22, 2024 at 18:00 UTC
c1880ac5c11bda08708cc4466691f77caf497bac
3 files changed
+20
-17
admin/src/OptionsPage.ts
+5
-5
@@ -57,7 +57,6 @@ export default function OptionsPage() {
57
}
58
const maxDownloadsDefaults = {
59
comp: NumberField,
60
- min: 0,
60
placeholder: "no limit",
61
toField: (x: any) => x || '',
62
sm: 4,
@@ -146,7 +145,7 @@ export default function OptionsPage() {
145
helperText: "Access Admin-panel without entering credentials"
146
},
147
149
- { k: 'proxies', comp: NumberField, min: 0, max: 9, label: "Number of HTTP proxies", placeholder: "none",
148
+ { k: 'proxies', comp: NumberField, max: 9, label: "Number of HTTP proxies", placeholder: "none",
149
error: proxyWarning(values, status),
150
helperText: "Wrong number will prevent detection of users' IP address"
151
},
@@ -182,7 +181,7 @@ export default function OptionsPage() {
181
182
{ k: 'auto_play_seconds', comp: NumberField, xs: 6, sm: 3, min: 1, max: 10000, required: true,
183
label: "Auto-play seconds delay", helperText: md(`Default value for the [Show interface](${REPO_URL}discussions/270)`) },
185
- { k: 'tile_size', comp: NumberField, xs: 6, sm: 3, min: 0, max: MAX_TILE_SIZE, required: true,
184
+ { k: 'tile_size', comp: NumberField, xs: 6, sm: 3, max: MAX_TILE_SIZE, required: true,
185
label: "Default tiles size", helperText: wikiLink('Tiles', "To enable tiles-mode") },
186
{ k: 'theme', comp: SelectField, xs: 6, sm: 3, options: THEME_OPTIONS },
187
{ k: 'sort_by', comp: SelectField, xs: 6, sm: 3, options: SORT_BY_OPTIONS },
@@ -196,7 +195,8 @@ export default function OptionsPage() {
195
h(Section, { title: "Uploads" }),
196
{ k: 'dont_overwrite_uploading', comp: BoolField, md: 4, label: "Uploads don't overwrite",
197
helperText: "Files will be numbered to avoid overwriting" },
199
- { k : CFG.split_uploads, comp: NumberField, unit: 'MB', md: 2, fromField: x => x * 1E6, toField: x => x ? x / 1E6 : null, min: 0, step: .1,
198
+ { k : CFG.split_uploads, comp: NumberField, unit: 'MB', md: 2, step: .1,
199
+ fromField: x => x * 1E6, toField: x => x ? x / 1E6 : null,
200
placeholder: "disabled", label: "Split uploads in chunks", helperText: "Overcome proxy limits" },
201
{ k: 'delete_unfinished_uploads_after', comp: NumberField, md: 3, min : 0, unit: "seconds", placeholder: "Never",
202
helperText: "Leave empty to never delete" },
@@ -206,7 +206,7 @@ export default function OptionsPage() {
206
h(Section, { title: "Others" }),
207
{ k: 'keep_session_alive', comp: BoolField, sm: 4, md: 6, helperText: "Keeps you logged in while the page is left open and the computer is on" },
208
{ k: 'session_duration', comp: NumberField, sm: 4, md: 3, min: 5, unit: "seconds", required: true },
209
- { k: 'zip_calculate_size_for_seconds', comp: NumberField, sm: 4, md: 3, unit: "seconds", required: true, min: 0,
209
+ { k: 'zip_calculate_size_for_seconds', comp: NumberField, sm: 4, md: 3, unit: "seconds", required: true,
210
label: "Calculate ZIP size for", helperText: "If time is not enough, the browser will not show download percentage" },
211
212
{ k: 'descript_ion', comp: BoolField, ...isWindows && { sm: 4, md: 3 }, label: "Enable comments", helperText: "In file DESCRIPT.ION" },
admin/src/importAccountsCsv.ts
+1
-1
@@ -37,7 +37,7 @@ export async function importAccountsCsv(cb?: () => void) {
37
save: { startIcon: h(Upload), children: 'Go' },
38
fields: [
39
h(Box, { p: 1 }, "Total lines:", rows.length),
40
- { k: 'skipFirstLines', comp: NumberField, min: 0, max: rows.length-1, typing: true, md: 6,
40
+ { k: 'skipFirstLines', comp: NumberField, max: rows.length-1, typing: true, md: 6,
41
helperText: h(Fragment, {}, "First line: ", h('code', {}, row.join(', ')) ),
42
},
43
{ k: 'overwriteExistingAccounts', comp: BoolField, md: 6 },
mui-grid-form/misc-fields.ts
+14
-11
@@ -4,16 +4,10 @@ import { createElement as h, useEffect, useState } from 'react'
4
import { StringField } from './StringField'
5
import { FieldProps } from '.'
6
import {
7
- Box,
8
- Checkbox,
9
- FormControl,
10
- FormControlLabel,
11
- FormGroup,
12
- FormHelperText,
13
- FormLabel,
14
- InputAdornment,
15
- Switch
7
+ Box, Checkbox, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, IconButton,
8
+ InputAdornment, Switch
9
} from '@mui/material'
10
+import { Cancel } from '@mui/icons-material'
11
import _ from 'lodash'
12
13
export function DisplayField({ value, empty='-', ...props }: any) {
@@ -22,7 +16,7 @@ export function DisplayField({ value, empty='-', ...props }: any) {
16
return h(StringField, { ...props, value, disabled: true })
17
}
18
25
-export function NumberField({ value, onChange, setApi, required, min, max, step, unit, ...props }: FieldProps<number | null>) {
19
+export function NumberField({ value, onChange, setApi, required, min=0, max, step, unit, clearable, ...props }: FieldProps<number | null>) {
20
setApi?.({
21
getError() {
22
return value == null ? (required ? "required" : false)
@@ -40,7 +34,16 @@ export function NumberField({ value, onChange, setApi, required, min, max, step,
34
},
35
inputProps: { min, max, step, },
36
InputProps: _.merge({
43
- sx: { '& input': { appearance: 'textfield' } }
37
+ sx: { '& input': { appearance: 'textfield' } },
38
+ startAdornment: (clearable ?? props.placeholder) && (value || value === 0) && h(InputAdornment, {
39
+ position: 'start',
40
+ }, h(IconButton, {
41
+ size: 'small',
42
+ edge: 'start',
43
+ sx: { ml: -1, opacity: .5 },
44
+ 'aria-label': "clear",
45
+ onClick(event){ onChange(null, { was: value, event }) }
46
+ }, h(Cancel))),
47
}, unit && {
48
sx: { pr: '6px', '& input': { pl: '.2em', textAlign: 'right' } },
49
endAdornment: h(InputAdornment, {