Compare commits

..

No commits in common. "d982b8dfb362a7311322cf9941c69ae626c77ccd" and "6ea5f2848ad7824cf5143c3bb0529845a1bbade8" have entirely different histories.

15 changed files with 277 additions and 531 deletions

View File

@ -34,7 +34,6 @@ import AuthCallback from './components/App/AuthCallback.jsx'
import EmailNotificationTemplate from './components/Email/EmailNotificationTemplate.jsx' import EmailNotificationTemplate from './components/Email/EmailNotificationTemplate.jsx'
import MarketplaceAuthCallback from './components/Dashboard/Sales/Marketplaces/MarketplaceAuthCallback.jsx' import MarketplaceAuthCallback from './components/Dashboard/Sales/Marketplaces/MarketplaceAuthCallback.jsx'
import AuthLaunch from './components/App/AppLaunch.jsx' import AuthLaunch from './components/App/AppLaunch.jsx'
import { TableStateProvider } from './components/Dashboard/context/TableStateContext.jsx'
const SlicerIntegration = lazy( const SlicerIntegration = lazy(
() => () =>
import('./components/Dashboard/Production/Printers/SlicerIntegration.jsx') import('./components/Dashboard/Production/Printers/SlicerIntegration.jsx')
@ -87,7 +86,6 @@ const AppContent = () => {
<NotificationProvider> <NotificationProvider>
<SpotlightProvider> <SpotlightProvider>
<ActionsModalProvider> <ActionsModalProvider>
<TableStateProvider>
<Routes> <Routes>
<Route <Route
path='/applaunch' path='/applaunch'
@ -158,7 +156,6 @@ const AppContent = () => {
} }
/> />
</Routes> </Routes>
</TableStateProvider>
</ActionsModalProvider> </ActionsModalProvider>
</SpotlightProvider> </SpotlightProvider>
</NotificationProvider> </NotificationProvider>

View File

@ -12,6 +12,7 @@ import DashboardBreadcrumb from './common/DashboardBreadcrumb'
import DeveloperSidebar from './Developer/DeveloperSidebar' import DeveloperSidebar from './Developer/DeveloperSidebar'
import { useThemeContext } from './context/ThemeContext' import { useThemeContext } from './context/ThemeContext'
import { MessageProvider } from './context/MessageContext' import { MessageProvider } from './context/MessageContext'
import { TableStateProvider } from './context/TableStateContext'
const { Content } = Layout const { Content } = Layout
@ -28,6 +29,7 @@ const DashboardLayout = ({ children }) => {
return ( return (
<MessageProvider> <MessageProvider>
<TableStateProvider>
<Layout <Layout
style={{ height: 'var(--unit-100vh)' }} style={{ height: 'var(--unit-100vh)' }}
className={isDarkMode ? 'dark-mode' : 'light-mode'} className={isDarkMode ? 'dark-mode' : 'light-mode'}
@ -62,6 +64,7 @@ const DashboardLayout = ({ children }) => {
</Layout> </Layout>
</Layout> </Layout>
</Layout> </Layout>
</TableStateProvider>
</MessageProvider> </MessageProvider>
) )
} }

View File

@ -33,7 +33,6 @@ import LoadFilamentStock from '../../Inventory/FilamentStocks/LoadFilamentStock.
import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock.jsx' import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock.jsx'
import ScrollBox from '../../common/ScrollBox.jsx' import ScrollBox from '../../common/ScrollBox.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx' import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import PrinterControlButtons from '../../common/PrinterControlButtons.jsx'
const log = loglevel.getLogger('ControlPrinter') const log = loglevel.getLogger('ControlPrinter')
log.setLevel(config.logLevel) log.setLevel(config.logLevel)
@ -183,7 +182,6 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
> >
<PrinterTemperaturePanel <PrinterTemperaturePanel
id={printerId} id={printerId}
offline={!objectFormState.objectData?.online}
disabled={ disabled={
!objectFormState.objectData?.online || objectFormState.loading !objectFormState.objectData?.online || objectFormState.loading
} }
@ -245,7 +243,6 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
> >
<PrinterMiscPanel <PrinterMiscPanel
id={printerId} id={printerId}
offline={!objectFormState.objectData?.online}
disabled={ disabled={
!objectFormState.objectData?.online || objectFormState.loading !objectFormState.objectData?.online || objectFormState.loading
} }
@ -275,8 +272,7 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
visibleActions={{ visibleActions={{
edit: false, edit: false,
info: !slicerIntegration, info: !slicerIntegration,
control: !slicerIntegration, control: !slicerIntegration
newPrinterProfile: !slicerIntegration
}} }}
objectData={objectFormState.objectData} objectData={objectFormState.objectData}
/> />
@ -322,26 +318,11 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
/> />
</Space> </Space>
</Space> </Space>
<Flex gap='small'>
<PrinterControlButtons
callAction={(action) =>
actionHandlerRef.current?.callAction(action)
}
objectData={objectFormState.objectData}
disabled={
!objectFormState.objectData?.online || objectFormState.loading
}
loading={objectFormState.loading}
/>
{!slicerIntegration && (
<ObjectTableNavigationButtons <ObjectTableNavigationButtons
showEndingDivider={true}
disabled={objectFormState.loading} disabled={objectFormState.loading}
_id={printerId} _id={printerId}
objectType='printer' objectType='printer'
/> />
)}
</Flex>
</Flex> </Flex>
<AlertsDisplay <AlertsDisplay

View File

@ -36,6 +36,8 @@ const FilePreview = ({ file, style = {} }) => {
} }
}, [file._id, file?.type, fetchPreview, token]) }, [file._id, file?.type, fetchPreview, token])
console.log(file)
if (loading == true || !file?.type) { if (loading == true || !file?.type) {
return <LoadingPlaceholder message={'Loading file preview...'} /> return <LoadingPlaceholder message={'Loading file preview...'} />
} }

View File

@ -1,10 +1,6 @@
import { useEffect, useRef, cloneElement, useMemo } from 'react' import { useEffect, useRef, cloneElement, useMemo } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Popover, Typography } from 'antd' import { Popover, Typography } from 'antd'
import loglevel from 'loglevel'
import config from '../../../config'
const logger = loglevel.getLogger('ApiServerContext')
logger.setLevel(config.logLevel)
const MODIFIER_ALIASES = { const MODIFIER_ALIASES = {
cmd: 'meta', cmd: 'meta',
@ -63,9 +59,7 @@ const KeyboardShortcut = ({
} }
if (log) { if (log) {
logger.info('Key Down:', key, 'Pressed Keys:', [ console.log('Key Down:', key, 'Pressed Keys:', [...pressedKeysRef.current])
...pressedKeysRef.current
])
} }
if ( if (

View File

@ -37,48 +37,9 @@ function filterActionsByVisibility(actions, visibleActions) {
}) })
} }
function cleanDividers(items) {
if (!Array.isArray(items) || items.length === 0) return []
const cleaned = []
for (const item of items) {
if (!item) continue
if (item.type === 'divider') {
if (cleaned.length === 0) continue
if (cleaned[cleaned.length - 1]?.type === 'divider') continue
cleaned.push(item)
continue
}
if (item.children && Array.isArray(item.children)) {
const children = cleanDividers(item.children)
if (children.length === 0) continue
cleaned.push({ ...item, children })
continue
}
cleaned.push(item)
}
if (cleaned[cleaned.length - 1]?.type === 'divider') {
cleaned.pop()
}
return cleaned
}
// Recursively map actions to AntD Dropdown items // Recursively map actions to AntD Dropdown items
function mapActionsToMenuItems( function mapActionsToMenuItems(actions, currentUrlWithActions, id, objectData) {
actions, return actions.map((action) => {
currentUrlWithActions,
id,
objectData,
userProfile
) {
return cleanDividers(
actions.map((action) => {
if (action.type === 'divider') { if (action.type === 'divider') {
return { type: 'divider' } return { type: 'divider' }
} }
@ -87,6 +48,8 @@ function mapActionsToMenuItems(
var disabled = actionUrl && actionUrl === currentUrlWithActions var disabled = actionUrl && actionUrl === currentUrlWithActions
var visible = true var visible = true
const { userProfile } = useContext(AuthContext)
if (action.disabled) { if (action.disabled) {
if (typeof action.disabled === 'function') { if (typeof action.disabled === 'function') {
disabled = action.disabled({ ...objectData, _user: userProfile }) disabled = action.disabled({ ...objectData, _user: userProfile })
@ -103,10 +66,6 @@ function mapActionsToMenuItems(
} }
} }
if (visible != true) {
return null
}
const item = { const item = {
key: action.key || action.name, key: action.key || action.name,
label: action.label, label: action.label,
@ -119,13 +78,13 @@ function mapActionsToMenuItems(
action.children, action.children,
currentUrlWithActions, currentUrlWithActions,
id, id,
objectData, objectData
userProfile
) )
} }
if (visible == true) {
return item return item
}
}) })
)
} }
const stripActionParam = (pathname, search) => { const stripActionParam = (pathname, search) => {
@ -149,7 +108,6 @@ const ObjectActions = ({
const navigate = useNavigate() const navigate = useNavigate()
const location = useLocation() const location = useLocation()
const { showActionsModal } = useActionsModal() const { showActionsModal } = useActionsModal()
const { userProfile } = useContext(AuthContext)
// Get current url without 'action' param // Get current url without 'action' param
const currentUrlWithoutActions = stripActionParam( const currentUrlWithoutActions = stripActionParam(
location.pathname, location.pathname,
@ -162,14 +120,11 @@ const ObjectActions = ({
visibleActions visibleActions
) )
const filteredActions = cleanDividers( const filteredActions = visibilityFilteredActions.filter(
visibilityFilteredActions.filter(
(action) => (action) =>
action.type === 'divider' ||
typeof action.url !== 'function' || typeof action.url !== 'function' ||
action.url(id) !== currentUrlWithoutActions action.url(id) !== currentUrlWithoutActions
) )
)
const currentUrlWithActions = location.pathname + location.search const currentUrlWithActions = location.pathname + location.search
@ -179,8 +134,7 @@ const ObjectActions = ({
filteredActions, filteredActions,
currentUrlWithActions, currentUrlWithActions,
id, id,
objectData, objectData
userProfile
), ),
onClick: (info) => { onClick: (info) => {
// Find the action by key // Find the action by key

View File

@ -127,6 +127,8 @@ const ObjectForm = forwardRef(
searchParams.delete(actionParam) searchParams.delete(actionParam)
const newSearch = searchParams.toString() const newSearch = searchParams.toString()
console.log('newSearch', newSearch)
console.log('location.pathname', location.pathname)
const newPath = location.pathname + (newSearch ? `?${newSearch}` : '') const newPath = location.pathname + (newSearch ? `?${newSearch}` : '')
navigate(newPath, { replace: true }) navigate(newPath, { replace: true })
}, },
@ -535,7 +537,7 @@ const ObjectForm = forwardRef(
} }
const activityUnsubscribe = subscribeToObjectActivity( const activityUnsubscribe = subscribeToObjectActivity(
id?.toLowerCase(), id,
type, type,
activityHandler activityHandler
) )
@ -563,7 +565,7 @@ const ObjectForm = forwardRef(
} }
const objectUpdatesUnsubscribe = subscribeToObjectUpdates( const objectUpdatesUnsubscribe = subscribeToObjectUpdates(
id?.toLowerCase(), id,
type, type,
objectUpdateHandler objectUpdateHandler
) )

View File

@ -693,7 +693,7 @@ const ObjectTable = forwardRef(
// Subscribe to new items only // Subscribe to new items only
newItemIds.forEach((itemId) => { newItemIds.forEach((itemId) => {
const unsubscribe = subscribeToObjectUpdates( const unsubscribe = subscribeToObjectUpdates(
itemId?.toLowerCase(), itemId,
type, type,
(updateData) => { (updateData) => {
updateEventHandlerRef.current(itemId, updateData) updateEventHandlerRef.current(itemId, updateData)

View File

@ -1,89 +0,0 @@
import { createElement, useContext } from 'react'
import { Button, Space } from 'antd'
import PropTypes from 'prop-types'
import { getModelByName } from '../../../database/ObjectModels'
import { AuthContext } from '../context/AuthContext'
import PlayCircleIcon from '../../Icons/PlayCircleIcon'
import PauseCircleIcon from '../../Icons/PauseCircleIcon'
import StopCircleIcon from '../../Icons/StopCircleIcon'
const findAction = (actions, name) => {
for (const action of actions) {
if (action.name === name) return action
if (action.children) {
const found = findAction(action.children, name)
if (found) return found
}
}
return null
}
const isActionDisabled = (action, objectData, userProfile, disabled) => {
if (disabled) return true
if (!action?.disabled) return false
if (typeof action.disabled === 'function') {
return action.disabled({ ...objectData, _user: userProfile })
}
return action.disabled
}
const PrinterControlButtons = ({ callAction, objectData, disabled }) => {
const { userProfile } = useContext(AuthContext)
const model = getModelByName('printer')
const startQueueAction = findAction(model.actions, 'startQueue')
const pauseJobAction = findAction(model.actions, 'pauseJob')
const resumeJobAction = findAction(model.actions, 'resumeJob')
const cancelJobAction = findAction(model.actions, 'cancelJob')
const isPaused = objectData?.state?.type === 'paused'
const startAction = isPaused ? resumeJobAction : startQueueAction
const startActionName = isPaused ? 'resumeJob' : 'startQueue'
return (
<Space size='small'>
<Button
icon={createElement(PlayCircleIcon)}
onClick={() => callAction(startActionName)}
disabled={isActionDisabled(
startAction,
objectData,
userProfile,
disabled
)}
title={startAction?.label}
/>
<Button
icon={createElement(PauseCircleIcon)}
onClick={() => callAction('pauseJob')}
disabled={isActionDisabled(
pauseJobAction,
objectData,
userProfile,
disabled
)}
title={pauseJobAction?.label}
/>
<Button
icon={createElement(StopCircleIcon)}
onClick={() => callAction('cancelJob')}
disabled={isActionDisabled(
cancelJobAction,
objectData,
userProfile,
disabled
)}
title={cancelJobAction?.label}
danger
/>
</Space>
)
}
PrinterControlButtons.propTypes = {
callAction: PropTypes.func.isRequired,
objectData: PropTypes.object.isRequired,
disabled: PropTypes.bool,
loading: PropTypes.bool
}
export default PrinterControlButtons

View File

@ -7,12 +7,7 @@ import merge from 'lodash/merge'
const { Text } = Typography const { Text } = Typography
const PrinterMiscPanel = ({ const PrinterMiscPanel = ({ id, showControls = true, disabled = false }) => {
id,
showControls = true,
disabled = false,
offline = true
}) => {
const { subscribeToObjectEvent, connected, sendObjectAction } = const { subscribeToObjectEvent, connected, sendObjectAction } =
useContext(ApiServerContext) useContext(ApiServerContext)
const controlsDisabled = disabled || !connected const controlsDisabled = disabled || !connected
@ -40,22 +35,10 @@ const PrinterMiscPanel = ({
const [lcdBrightness, setLcdBrightness] = useState(0) const [lcdBrightness, setLcdBrightness] = useState(0)
const [beeperValue, setBeeperValue] = useState(0) const [beeperValue, setBeeperValue] = useState(0)
useEffect(() => {
if (offline) {
setMiscData({
fan: { speed: 0, target: 0 },
lcdBacklight: { brightness: 0 },
beeper: { value: 0 },
filamentSensor: { enabled: false, filamentDetected: false },
coolingFan: { speed: 0 }
})
}
}, [offline])
useEffect(() => { useEffect(() => {
if (id && connected == true) { if (id && connected == true) {
const miscEventUnsubscribe = subscribeToObjectEvent( const miscEventUnsubscribe = subscribeToObjectEvent(
id?.toLowerCase(), id,
'printer', 'printer',
'misc', 'misc',
(event) => { (event) => {
@ -210,8 +193,7 @@ const PrinterMiscPanel = ({
PrinterMiscPanel.propTypes = { PrinterMiscPanel.propTypes = {
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
showControls: PropTypes.bool, showControls: PropTypes.bool,
disabled: PropTypes.bool, disabled: PropTypes.bool
offline: PropTypes.bool
} }
export default PrinterMiscPanel export default PrinterMiscPanel

View File

@ -30,23 +30,11 @@ const CustomCollapse = styled(Collapse)`
} }
` `
const controlLabelStyle = {
whiteSpace: 'nowrap',
flexShrink: 0,
minWidth: '120px'
}
const controlInputStyle = {
flex: 1,
minWidth: 0
}
const PrinterPositionPanel = ({ const PrinterPositionPanel = ({
id, id,
showControls = true, showControls = true,
showMoreInfo = true, showMoreInfo = true,
disabled = false, disabled = false
offline = true
}) => { }) => {
const { subscribeToObjectEvent, connected, sendObjectAction } = const { subscribeToObjectEvent, connected, sendObjectAction } =
useContext(ApiServerContext) useContext(ApiServerContext)
@ -67,30 +55,10 @@ const PrinterPositionPanel = ({
minCruiseRatio: 0 minCruiseRatio: 0
}) })
useEffect(() => {
if (offline) {
setPositionData({
speedFactor: 1.0,
speed: 100,
extrudeFactor: 1.0,
absoluteCoordinates: true,
absoluteExtrude: false,
homingOrigin: [0.0, 0.0, 0.0, 0.0],
toolheadPosition: [0.0, 0.0, 0.0, 0.0],
gcodePosition: [0.0, 0.0, 0.0, 0.0],
livePosition: [0.0, 0.0, 0.0, 0.0],
maxVelocity: 1000,
maxAcceleration: 1000,
squareCornerVelocity: 100,
minCruiseRatio: 0
})
}
}, [offline])
useEffect(() => { useEffect(() => {
if (id && connected == true) { if (id && connected == true) {
const motionEventUnsubscribe = subscribeToObjectEvent( const motionEventUnsubscribe = subscribeToObjectEvent(
id?.toLowerCase(), id,
'printer', 'printer',
'motion', 'motion',
(event) => { (event) => {
@ -105,7 +73,6 @@ const PrinterPositionPanel = ({
} }
} }
}, [id, connected, subscribeToObjectEvent]) }, [id, connected, subscribeToObjectEvent])
const [speedFactor, setSpeedFactor] = useState(positionData.speedFactor) const [speedFactor, setSpeedFactor] = useState(positionData.speedFactor)
const [extrudeFactor, setExtrudeFactor] = useState(positionData.extrudeFactor) const [extrudeFactor, setExtrudeFactor] = useState(positionData.extrudeFactor)
const [maxVelocity, setMaxVelocity] = useState(positionData.maxVelocity) const [maxVelocity, setMaxVelocity] = useState(positionData.maxVelocity)
@ -245,22 +212,16 @@ const PrinterPositionPanel = ({
</Descriptions> </Descriptions>
{showControls && ( {showControls && (
<> <>
<Flex vertical gap='small' style={{ width: '100%' }}> <Space direction='vertical' style={{ width: '100%' }}>
<Flex align='center' style={{ width: '100%' }}> <Space direction='horizontal'>
<Text style={{ ...controlLabelStyle, minWidth: '91px' }}> <Text>Max Velocity:</Text>
Max Velocity: <Space.Compact block size='small'>
</Text>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(maxVelocity, 2)} value={round(maxVelocity, 2)}
min={1} min={1}
max={10000} max={10000}
step={5} step={5}
style={controlInputStyle} style={{ width: '125px' }}
suffix='mm/s' suffix='mm/s'
onChange={(value) => setMaxVelocity(value)} onChange={(value) => setMaxVelocity(value)}
onPressEnter={handleSetMaxVelocity} onPressEnter={handleSetMaxVelocity}
@ -276,23 +237,18 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
<Flex align='center' style={{ width: '100%' }}> <Space direction='vertical' style={{ width: '100%' }}>
<Text style={{ ...controlLabelStyle, minWidth: '120px' }}> <Space direction='horizontal'>
Max Acceleration: <Text>Max Acceleration:</Text>
</Text> <Space.Compact block size='small'>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(maxAcceleration, 2)} value={round(maxAcceleration, 2)}
min={1} min={1}
max={10000} max={10000}
step={5} step={5}
style={controlInputStyle} style={{ width: '125px' }}
suffix='mm/s²' suffix='mm/s²'
onChange={(value) => setMaxAcceleration(value)} onChange={(value) => setMaxAcceleration(value)}
onPressEnter={handleSetMaxAcceleration} onPressEnter={handleSetMaxAcceleration}
@ -308,24 +264,20 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
</Space>
<Flex align='center' style={{ width: '100%' }}> <Space direction='vertical' style={{ width: '100%' }}>
<Text style={{ ...controlLabelStyle, minWidth: '102px' }}> <Space direction='horizontal'>
Sqr Corner Vel: <Text>Sqr Corner Vel:</Text>
</Text> <Space.Compact block size='small'>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(squareCornerVelocity, 2) || 0} value={round(squareCornerVelocity, 2) || 0}
min={0.1} min={0.1}
max={1000} max={1000}
step={0.1} step={0.1}
style={controlInputStyle}
suffix='mm/s' suffix='mm/s'
style={{ width: '125px' }}
onChange={(value) => setSquareCornerVelocity(value)} onChange={(value) => setSquareCornerVelocity(value)}
onPressEnter={handleSetSquareCornerVelocity} onPressEnter={handleSetSquareCornerVelocity}
size='small' size='small'
@ -340,24 +292,20 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
</Space>
<Flex align='center' style={{ width: '100%' }}> <Space direction='vertical' style={{ width: '100%' }}>
<Text style={{ ...controlLabelStyle, minWidth: '114px' }}> <Space direction='horizontal'>
Min Cruise Ratio: <Text>Min Cruise Ratio:</Text>
</Text> <Space.Compact block size='small'>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(minCruiseRatio * 100, 2) || 0} value={round(minCruiseRatio * 100, 2) || 0}
min={0} min={0}
max={100} max={100}
step={1} step={1}
suffix='%' suffix='%'
style={controlInputStyle} style={{ width: '125px' }}
onChange={(value) => setMinCruiseRatio(value / 100)} onChange={(value) => setMinCruiseRatio(value / 100)}
onPressEnter={handleSetMinCruiseRatio} onPressEnter={handleSetMinCruiseRatio}
size='small' size='small'
@ -372,8 +320,9 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
</Flex> </Space>
</Space>
</> </>
)} )}
<Text>Homing Origin:</Text> <Text>Homing Origin:</Text>
@ -449,22 +398,16 @@ const PrinterPositionPanel = ({
</Descriptions> </Descriptions>
{showControls && ( {showControls && (
<> <>
<Flex vertical gap='small' style={{ width: '100%' }}> <Space direction='vertical' style={{ width: '100%' }}>
<Flex align='center' style={{ width: '100%' }}> <Space direction='horizontal'>
<Text style={{ ...controlLabelStyle, minWidth: '96px' }}> <Text>Speed Factor:</Text>
Speed Factor: <Space.Compact block size='small'>
</Text>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(speedFactor, 2)} value={round(speedFactor, 2)}
min={0.1} min={0.1}
max={2} max={2}
step={0.1} step={0.1}
style={controlInputStyle} style={{ width: '125px' }}
suffix='%' suffix='%'
onChange={(value) => setSpeedFactor(value)} onChange={(value) => setSpeedFactor(value)}
onPressEnter={handleSetSpeedFactor} onPressEnter={handleSetSpeedFactor}
@ -480,23 +423,17 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
<Flex align='center' style={{ width: '100%' }}> <Space direction='horizontal'>
<Text style={{ ...controlLabelStyle, minWidth: '105px' }}> <Text>Extrude Factor:</Text>
Extrude Factor: <Space.Compact block size='small'>
</Text>
<Space.Compact
block
size='small'
style={{ flex: 1, minWidth: 0 }}
>
<InputNumber <InputNumber
value={round(extrudeFactor, 2)} value={round(extrudeFactor, 2)}
min={0.1} min={0.1}
max={2} max={2}
step={0.1} step={0.1}
style={controlInputStyle} style={{ width: '125px' }}
suffix='%' suffix='%'
onChange={(value) => setExtrudeFactor(value)} onChange={(value) => setExtrudeFactor(value)}
onPressEnter={handleSetExtrudeFactor} onPressEnter={handleSetExtrudeFactor}
@ -512,8 +449,8 @@ const PrinterPositionPanel = ({
Set Set
</Button> </Button>
</Space.Compact> </Space.Compact>
</Flex> </Space>
</Flex> </Space>
</> </>
)} )}
<Descriptions <Descriptions
@ -572,8 +509,7 @@ PrinterPositionPanel.propTypes = {
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
showControls: PropTypes.bool, showControls: PropTypes.bool,
showMoreInfo: PropTypes.bool, showMoreInfo: PropTypes.bool,
disabled: PropTypes.bool, disabled: PropTypes.bool
offline: PropTypes.bool
} }
export default PrinterPositionPanel export default PrinterPositionPanel

View File

@ -38,8 +38,7 @@ const PrinterTemperaturePanel = ({
showExtruder = true, showExtruder = true,
showBed = true, showBed = true,
showMoreInfo = true, showMoreInfo = true,
disabled = false, disabled = false
offline = true
}) => { }) => {
const [temperatureData, setTemperatureData] = useState({ const [temperatureData, setTemperatureData] = useState({
extruder: { extruder: {
@ -56,17 +55,6 @@ const PrinterTemperaturePanel = ({
ambiant: 0 ambiant: 0
}) })
useEffect(() => {
if (offline) {
setTemperatureData({
extruder: { current: 0, target: 0, power: 0 },
bed: { current: 0, target: 0, power: 0 },
pinda: 0,
ambiant: 0
})
}
}, [offline])
const { subscribeToObjectEvent, connected, sendObjectAction } = const { subscribeToObjectEvent, connected, sendObjectAction } =
useContext(ApiServerContext) useContext(ApiServerContext)
const controlsDisabled = disabled || !connected const controlsDisabled = disabled || !connected
@ -84,9 +72,9 @@ const PrinterTemperaturePanel = ({
}, [temperatureData.bed?.target]) }, [temperatureData.bed?.target])
useEffect(() => { useEffect(() => {
if (id && connected == true && offline == false) { if (id && connected == true) {
const temperatureEventUnsubscribe = subscribeToObjectEvent( const temperatureEventUnsubscribe = subscribeToObjectEvent(
id?.toLowerCase(), id,
'printer', 'printer',
'temperature', 'temperature',
(event) => { (event) => {
@ -100,7 +88,7 @@ const PrinterTemperaturePanel = ({
if (temperatureEventUnsubscribe) temperatureEventUnsubscribe() if (temperatureEventUnsubscribe) temperatureEventUnsubscribe()
} }
} }
}, [id, connected, subscribeToObjectEvent, offline]) }, [id, connected, subscribeToObjectEvent])
const [extruderTarget, setExtruderTarget] = useState(0) const [extruderTarget, setExtruderTarget] = useState(0)
const [bedTarget, setBedTarget] = useState(0) const [bedTarget, setBedTarget] = useState(0)
@ -189,7 +177,7 @@ const PrinterTemperaturePanel = ({
value={extruderTarget} value={extruderTarget}
min={0} min={0}
max={300} max={300}
style={{ width: '140px' }} style={{ width: '120px' }}
addonAfter='°C' addonAfter='°C'
onChange={(value) => setExtruderTarget(value || 0)} onChange={(value) => setExtruderTarget(value || 0)}
onPressEnter={() => onPressEnter={() =>
@ -253,7 +241,7 @@ const PrinterTemperaturePanel = ({
value={bedTarget} value={bedTarget}
min={0} min={0}
max={300} max={300}
style={{ width: '140px' }} style={{ width: '120px' }}
addonAfter='°C' addonAfter='°C'
onChange={(value) => setBedTarget(value || 0)} onChange={(value) => setBedTarget(value || 0)}
onPressEnter={() => onPressEnter={() =>
@ -321,8 +309,7 @@ PrinterTemperaturePanel.propTypes = {
showBed: PropTypes.bool, showBed: PropTypes.bool,
showMoreInfo: PropTypes.bool, showMoreInfo: PropTypes.bool,
shouldUnsubscribe: PropTypes.bool, shouldUnsubscribe: PropTypes.bool,
disabled: PropTypes.bool, disabled: PropTypes.bool
offline: PropTypes.bool
} }
export default PrinterTemperaturePanel export default PrinterTemperaturePanel

View File

@ -42,6 +42,7 @@ const Thumbnail = function Thumbnail({
borderRadius: '5px', borderRadius: '5px',
width: size, width: size,
height: size, height: size,
border: 'none',
...style ...style
} }
@ -150,7 +151,7 @@ const Thumbnail = function Thumbnail({
<Card <Card
className={className} className={className}
style={cardStyle} style={cardStyle}
styles={{ body: { padding: 0, height: '100%', width: style?.width } }} styles={{ body: { padding: 0, height: '100%' } }}
> >
<Flex justify='center' align='center' style={{ height: '100%' }}> <Flex justify='center' align='center' style={{ height: '100%' }}>
{fallback || ( {fallback || (

View File

@ -1510,7 +1510,7 @@ const ApiServerProvider = ({ children }) => {
} }
} }
const fetchFileThumbnail = async (file, size, show404Error = false) => { const fetchFileThumbnail = async (file, size) => {
try { try {
const response = await axios.get( const response = await axios.get(
`${config.backendUrl}/files/${file._id}/thumbnail`, `${config.backendUrl}/files/${file._id}/thumbnail`,
@ -1528,9 +1528,6 @@ const ApiServerProvider = ({ children }) => {
}) })
return window.URL.createObjectURL(blob) return window.URL.createObjectURL(blob)
} catch (err) { } catch (err) {
if (err.response.status === 404 && show404Error == false) {
return null
}
console.error(err) console.error(err)
showError(err, () => { showError(err, () => {
fetchFileThumbnail(file, size) fetchFileThumbnail(file, size)

View File

@ -164,7 +164,6 @@ export const GCodeFile = {
showPreview: false, showPreview: false,
showHyperlink: true, showHyperlink: true,
masterFilter: ['.gcode', '.g'], masterFilter: ['.gcode', '.g'],
thumbnail: true,
columnWidth: 200 columnWidth: 200
}, },
{ {