fix: (regression 0.49.0) admin/options: bad mobile layout

Massimo Melina committed Oct 28, 2023 at 21:41 UTC 667a39de6245ba64d4065e2be1338f616571c993
3 files changed +19 -5
admin/src/ConfigFilePage.ts
+3 -2
@@ -1,6 +1,6 @@
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, Fragment, useEffect, useRef, useState } from 'react';
3 +import { createElement as h, Fragment, useEffect, useState } from 'react';
4 import { apiCall, useApiEx } from './api'
5 import { Alert, Box } from '@mui/material'
6 import { Btn, Flex, IconBtn, isCtrlKey, KeepInScreen, modifiedSx, reloadBtn } from './misc';
@@ -19,7 +19,7 @@ export default function ConfigFilePage() {
19 useEffect(() => { setSaved(data?.text) }, [data])
20 useEffect(() => { saved !== undefined && setText(saved || '') }, [saved])
21 return h(Fragment, {},
22 - h(Flex, { alignItems: 'center' },
22 + h(Flex, { alignItems: 'center', flexWrap: 'wrap', justifyContent: 'space-between' },
23 h(Btn, { icon: ContentCopy, onClick: copy }, "Copy excluding passwords"),
24 edit ? h(Fragment, {},
25 reloadBtn(reload),
@@ -33,6 +33,7 @@ export default function ConfigFilePage() {
33 ) : h(Btn, {
34 icon: EditNote,
35 variant: 'outlined',
36 + labelFrom: 'sm',
37 onClick() {
38 setEdit(true)
39 const el = document.querySelector('main textarea')
admin/src/OptionsPage.ts
+3 -2
@@ -7,7 +7,7 @@ import { state, useSnapState } from './state'
7 import { Link as RouterLink } from 'react-router-dom'
8 import { CardMembership, EditNote, Refresh, Warning } from '@mui/icons-material'
9 import { Dict, iconTooltip, InLink, LinkBtn, MAX_TILES_SIZE, modifiedSx, REPO_URL, ipLocalHost,
10 - wait, wikiLink, with_, try_, ipForUrl } from './misc'
10 + wait, wikiLink, with_, try_, ipForUrl, useBreakpoint } from './misc'
11 import { Form, BoolField, NumberField, SelectField, FieldProps, Field, StringField } from '@hfs/mui-grid-form';
12 import { ArrayField } from './ArrayField'
13 import FileField from './FileField'
@@ -47,6 +47,7 @@ export default function OptionsPage() {
47 const reloadStatus = exposedReloadStatus = statusApi.reload
48 useEffect(() => void(reloadStatus()), [data]) //eslint-disable-line
49 useEffect(() => () => exposedReloadStatus = undefined, []) // clear on unmount
50 + const sm = useBreakpoint('sm')
51
52 const admins = useApiEx('get_admins').data?.list
53
@@ -88,7 +89,7 @@ export default function OptionsPage() {
89 component: RouterLink,
90 to: "/edit",
91 startIcon: h(EditNote),
91 - }, "Edit config file"),
92 + }, sm ? "Edit config file" : "File"),
93 ],
94 defaults() {
95 return { sm: 6 }
admin/src/mui.ts
+13 -1
@@ -137,11 +137,12 @@ interface BtnProps extends Omit<LoadingButtonProps,'disabled'|'title'|'onClick'>
137 progress?: boolean | number
138 link?: string
139 confirm?: boolean | string
140 + labelFrom?: Breakpoint
141 doneMessage?: boolean | string // displayed only if the result of onClick !== false
142 tooltipProps?: TooltipProps
143 onClick: (...args: Parameters<NonNullable<ButtonProps['onClick']>>) => Promisable<any>
144 }
144 -export function Btn({ icon, title, onClick, disabled, progress, link, tooltipProps, confirm, doneMessage, ...rest }: BtnProps) {
145 +export function Btn({ icon, title, onClick, disabled, progress, link, tooltipProps, confirm, doneMessage, labelFrom, children, ...rest }: BtnProps) {
146 const [loading, setLoading] = useStateMounted(false)
147 if (typeof disabled === 'string') {
148 title = disabled
@@ -149,6 +150,7 @@ export function Btn({ icon, title, onClick, disabled, progress, link, tooltipPro
150 }
151 if (link)
152 onClick = () => window.open(link)
153 + const showLabel = useBreakpoint(labelFrom || 'xs')
154 let ret: ReturnType<FC> = h(LoadingButton, {
155 variant: 'contained',
156 startIcon: icon && h(icon),
@@ -158,6 +160,16 @@ export function Btn({ icon, title, onClick, disabled, progress, link, tooltipPro
160 : h(CircularProgress, { size: '1rem', value: progress*100, variant: 'determinate' }),
161 disabled,
162 ...rest,
163 + children: showLabel && children,
164 + sx: {
165 + ...rest.sx,
166 + ...!showLabel && {
167 + minWidth: 'auto',
168 + px: 2,
169 + py: '7px',
170 + '& span': { mx:0 },
171 + }
172 + },
173 async onClick(...args) {
174 if (confirm && !await confirmDialog(confirm === true ? "Are you sure?" : confirm)) return
175 const ret = onClick?.apply(this,args)