Refactor GCodePreview and GCodeLegend Components for Improved Rendering and Interaction
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Updated GCodePreview to conditionally render the GCodeLegend based on line type, enhancing the user interface for different modes.
- Simplified the loading overlay in GCodePreview for better visibility and responsiveness during loading states.
- Replaced InputNumber with InputNumberCal in GCodeLegend for improved functionality and user experience.
- Adjusted styles and layout in both components to ensure consistent presentation and interaction across different scenarios.
This commit is contained in:
Tom Butcher 2026-11-09 01:39:12 +00:00
parent 0e9b6392c2
commit 6daba1cec8
2 changed files with 50 additions and 49 deletions

View File

@ -710,6 +710,22 @@ function GCodePreview(props) {
const loadingLabel = loader.planning
? 'Calculating motion...'
: `Parsing G-code... ${segmentCount.toLocaleString()} moves`
const isLineType = mode.kind === 'category'
const legend =
model && (ready || segmentCount > 0) ? (
<GCodeLegend
mode={mode}
model={model}
isDarkMode={isDarkMode}
hiddenTypes={hiddenTypes}
onToggleType={toggleType}
showTravel={showTravel}
onToggleTravel={() => setShowTravel((prev) => !prev)}
range={displayRange}
autoRange={autoRange || displayRange}
onRangeChange={handleRangeChange}
/>
) : null
return (
<Flex
@ -808,22 +824,14 @@ function GCodePreview(props) {
/>
</>
) : null}
{legend && !isLineType ? (
<Flex align='center' style={{ marginLeft: 'auto', flex: '0 0 auto' }}>
{legend}
</Flex>
) : null}
</Flex>
{model && (ready || segmentCount > 0) ? (
<GCodeLegend
mode={mode}
model={model}
isDarkMode={isDarkMode}
hiddenTypes={hiddenTypes}
onToggleType={toggleType}
showTravel={showTravel}
onToggleTravel={() => setShowTravel((prev) => !prev)}
range={displayRange}
autoRange={autoRange || displayRange}
onRangeChange={handleRangeChange}
/>
) : null}
{legend && isLineType ? legend : null}
<div
ref={paneRef}
@ -887,27 +895,26 @@ function GCodePreview(props) {
) : null}
{loader.status === 'loading' ? (
<div
style={{
position: 'absolute',
top: 12,
left: '50%',
transform: 'translateX(-50%)',
zIndex: 3,
width: 'min(320px, calc(100% - 24px))',
pointerEvents: 'none'
}}
<div className='previewProgressOverlay visible'>
<Flex
style={{ width: '100%', height: '100%' }}
align='center'
justify='center'
>
<Card
size='small'
className='previewZoomCard'
style={{ borderRadius: 12 }}
styles={{ body: { padding: '8px 12px' } }}
style={{
maxWidth: 360,
minWidth: 100,
width: '100%',
margin: 24
}}
styles={{ body: { padding: 18 } }}
>
<ProgressDisplay percent={loadingPercent} status='active'>
{loadingLabel}
</ProgressDisplay>
</Card>
</Flex>
</div>
) : null}

View File

@ -1,7 +1,8 @@
import PropTypes from 'prop-types'
import { Button, Flex, InputNumber, Typography } from 'antd'
import { Button, Flex, Typography } from 'antd'
import { FEATURE, FEATURE_INFO } from './featureTypes.js'
import { TOOL_PALETTE, rampCss } from './colorModes.js'
import InputNumberCal from '../../../Dashboard/common/InputNumberCal.jsx'
const { Text } = Typography
@ -151,21 +152,19 @@ function GCodeLegend({
autoRange != null &&
(range.min !== autoRange.min || range.max !== autoRange.max)
const isDuration = mode.stat === 'layerTime'
const unitSuffix = mode.unit || undefined
return (
<Flex gap='small' align='center' wrap='wrap' justify='center'>
<Text style={{ color: textColor, fontSize: 14, lineHeight: 1 }}>
{mode.label}
</Text>
{isDuration ? (
<Text style={{ color: textColor, fontSize: 14 }}>{format(min)}</Text>
) : (
<InputNumber
size='small'
<InputNumberCal
value={Number(min.toFixed(2))}
onChange={(value) =>
Number.isFinite(value) && onRangeChange({ min: value, max })
}
style={{ width: 80 }}
suffix={unitSuffix}
style={{ width: 100 }}
controls={false}
/>
)}
@ -180,21 +179,16 @@ function GCodeLegend({
{isDuration ? (
<Text style={{ color: textColor, fontSize: 14 }}>{format(max)}</Text>
) : (
<InputNumber
size='small'
<InputNumberCal
value={Number(max.toFixed(2))}
onChange={(value) =>
Number.isFinite(value) && onRangeChange({ min, max: value })
}
style={{ width: 80 }}
suffix={unitSuffix}
style={{ width: 100 }}
controls={false}
/>
)}
{mode.unit ? (
<Text type='secondary' style={{ fontSize: 12 }}>
{mode.unit}
</Text>
) : null}
{overridden ? (
<Button size='small' type='link' onClick={() => onRangeChange(null)}>
Reset range