Compare commits
No commits in common. "d982b8dfb362a7311322cf9941c69ae626c77ccd" and "6ea5f2848ad7824cf5143c3bb0529845a1bbade8" have entirely different histories.
d982b8dfb3
...
6ea5f2848a
141
src/App.jsx
141
src/App.jsx
@ -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,78 +86,76 @@ const AppContent = () => {
|
|||||||
<NotificationProvider>
|
<NotificationProvider>
|
||||||
<SpotlightProvider>
|
<SpotlightProvider>
|
||||||
<ActionsModalProvider>
|
<ActionsModalProvider>
|
||||||
<TableStateProvider>
|
<Routes>
|
||||||
<Routes>
|
<Route
|
||||||
<Route
|
path='/applaunch'
|
||||||
path='/applaunch'
|
element={<AuthLaunch />}
|
||||||
element={<AuthLaunch />}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/dashboard/electron/spotlightcontent'
|
||||||
path='/dashboard/electron/spotlightcontent'
|
element={
|
||||||
element={
|
<PrivateRoute
|
||||||
<PrivateRoute
|
component={() => (
|
||||||
component={() => (
|
<ElectronSpotlightContentPage />
|
||||||
<ElectronSpotlightContentPage />
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/'
|
||||||
path='/'
|
element={
|
||||||
element={
|
<PrivateRoute
|
||||||
<PrivateRoute
|
component={() => (
|
||||||
component={() => (
|
<Navigate
|
||||||
<Navigate
|
to='/dashboard/production/overview'
|
||||||
to='/dashboard/production/overview'
|
replace
|
||||||
replace
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/auth/callback'
|
||||||
path='/auth/callback'
|
element={<AuthCallback />}
|
||||||
element={<AuthCallback />}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/auth/marketplace/callback'
|
||||||
path='/auth/marketplace/callback'
|
element={<MarketplaceAuthCallback />}
|
||||||
element={<MarketplaceAuthCallback />}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/email/notification'
|
||||||
path='/email/notification'
|
element={<EmailNotificationTemplate />}
|
||||||
element={<EmailNotificationTemplate />}
|
/>
|
||||||
/>
|
<Route
|
||||||
<Route
|
path='/slicer'
|
||||||
path='/slicer'
|
element={<SlicerIntegration />}
|
||||||
element={<SlicerIntegration />}
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path='/dashboard'
|
path='/dashboard'
|
||||||
element={
|
element={
|
||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
component={() => <Dashboard />}
|
component={() => <Dashboard />}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{ProductionRoutes}
|
{ProductionRoutes}
|
||||||
{InventoryRoutes}
|
{InventoryRoutes}
|
||||||
{FinanceRoutes}
|
{FinanceRoutes}
|
||||||
{SalesRoutes}
|
{SalesRoutes}
|
||||||
{ManagementRoutes}
|
{ManagementRoutes}
|
||||||
{DeveloperRoutes}
|
{DeveloperRoutes}
|
||||||
</Route>
|
</Route>
|
||||||
<Route
|
<Route
|
||||||
path='*'
|
path='*'
|
||||||
element={
|
element={
|
||||||
<AppError
|
<AppError
|
||||||
message='Error 404. Page not found.'
|
message='Error 404. Page not found.'
|
||||||
showRefresh={false}
|
showRefresh={false}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</TableStateProvider>
|
|
||||||
</ActionsModalProvider>
|
</ActionsModalProvider>
|
||||||
</SpotlightProvider>
|
</SpotlightProvider>
|
||||||
</NotificationProvider>
|
</NotificationProvider>
|
||||||
|
|||||||
@ -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,40 +29,42 @@ const DashboardLayout = ({ children }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MessageProvider>
|
<MessageProvider>
|
||||||
<Layout
|
<TableStateProvider>
|
||||||
style={{ height: 'var(--unit-100vh)' }}
|
<Layout
|
||||||
className={isDarkMode ? 'dark-mode' : 'light-mode'}
|
style={{ height: 'var(--unit-100vh)' }}
|
||||||
>
|
className={isDarkMode ? 'dark-mode' : 'light-mode'}
|
||||||
<DashboardNavigation />
|
>
|
||||||
<Layout>
|
<DashboardNavigation />
|
||||||
{isProduction ? (
|
<Layout>
|
||||||
<ProductionSidebar />
|
{isProduction ? (
|
||||||
) : isInventory ? (
|
<ProductionSidebar />
|
||||||
<InventorySidebar />
|
) : isInventory ? (
|
||||||
) : isFinance ? (
|
<InventorySidebar />
|
||||||
<FinanceSidebar />
|
) : isFinance ? (
|
||||||
) : isSales ? (
|
<FinanceSidebar />
|
||||||
<SalesSidebar />
|
) : isSales ? (
|
||||||
) : isManagement ? (
|
<SalesSidebar />
|
||||||
<ManagementSidebar />
|
) : isManagement ? (
|
||||||
) : isDeveloper ? (
|
<ManagementSidebar />
|
||||||
<DeveloperSidebar />
|
) : isDeveloper ? (
|
||||||
) : (
|
<DeveloperSidebar />
|
||||||
<ProductionSidebar /> // Default to production sidebar
|
) : (
|
||||||
)}
|
<ProductionSidebar /> // Default to production sidebar
|
||||||
<Layout style={{ padding: '24px' }}>
|
)}
|
||||||
<Content>
|
<Layout style={{ padding: '24px' }}>
|
||||||
<Flex vertical style={{ height: '100%' }} gap='20px'>
|
<Content>
|
||||||
<Flex justify='space-between'>
|
<Flex vertical style={{ height: '100%' }} gap='20px'>
|
||||||
<DashboardBreadcrumb style={{ margin: '16px 0' }} />
|
<Flex justify='space-between'>
|
||||||
</Flex>
|
<DashboardBreadcrumb style={{ margin: '16px 0' }} />
|
||||||
|
</Flex>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Content>
|
</Content>
|
||||||
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</TableStateProvider>
|
||||||
</MessageProvider>
|
</MessageProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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'>
|
<ObjectTableNavigationButtons
|
||||||
<PrinterControlButtons
|
disabled={objectFormState.loading}
|
||||||
callAction={(action) =>
|
_id={printerId}
|
||||||
actionHandlerRef.current?.callAction(action)
|
objectType='printer'
|
||||||
}
|
/>
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={
|
|
||||||
!objectFormState.objectData?.online || objectFormState.loading
|
|
||||||
}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
{!slicerIntegration && (
|
|
||||||
<ObjectTableNavigationButtons
|
|
||||||
showEndingDivider={true}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
_id={printerId}
|
|
||||||
objectType='printer'
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<AlertsDisplay
|
<AlertsDisplay
|
||||||
|
|||||||
@ -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...'} />
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 (
|
||||||
|
|||||||
@ -37,95 +37,54 @@ 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,
|
if (action.type === 'divider') {
|
||||||
id,
|
return { type: 'divider' }
|
||||||
objectData,
|
}
|
||||||
userProfile
|
const actionUrl = action.url ? action.url(id) : undefined
|
||||||
) {
|
|
||||||
return cleanDividers(
|
|
||||||
actions.map((action) => {
|
|
||||||
if (action.type === 'divider') {
|
|
||||||
return { type: 'divider' }
|
|
||||||
}
|
|
||||||
const actionUrl = action.url ? action.url(id) : undefined
|
|
||||||
|
|
||||||
var disabled = actionUrl && actionUrl === currentUrlWithActions
|
var disabled = actionUrl && actionUrl === currentUrlWithActions
|
||||||
var visible = true
|
var visible = true
|
||||||
|
|
||||||
if (action.disabled) {
|
const { userProfile } = useContext(AuthContext)
|
||||||
if (typeof action.disabled === 'function') {
|
|
||||||
disabled = action.disabled({ ...objectData, _user: userProfile })
|
|
||||||
} else {
|
|
||||||
disabled = action.disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.visible) {
|
if (action.disabled) {
|
||||||
if (typeof action.visible === 'function') {
|
if (typeof action.disabled === 'function') {
|
||||||
visible = action.visible(objectData)
|
disabled = action.disabled({ ...objectData, _user: userProfile })
|
||||||
} else {
|
} else {
|
||||||
visible = action.visible
|
disabled = action.disabled
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (visible != true) {
|
if (action.visible) {
|
||||||
return null
|
if (typeof action.visible === 'function') {
|
||||||
|
visible = action.visible(objectData)
|
||||||
|
} else {
|
||||||
|
visible = action.visible
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const item = {
|
const item = {
|
||||||
key: action.key || action.name,
|
key: action.key || action.name,
|
||||||
label: action.label,
|
label: action.label,
|
||||||
danger: action?.danger || false,
|
danger: action?.danger || false,
|
||||||
icon: action.icon ? createElement(action.icon) : undefined,
|
icon: action.icon ? createElement(action.icon) : undefined,
|
||||||
disabled
|
disabled
|
||||||
}
|
}
|
||||||
if (action.children && Array.isArray(action.children)) {
|
if (action.children && Array.isArray(action.children)) {
|
||||||
item.children = mapActionsToMenuItems(
|
item.children = 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,13 +120,10 @@ const ObjectActions = ({
|
|||||||
visibleActions
|
visibleActions
|
||||||
)
|
)
|
||||||
|
|
||||||
const filteredActions = cleanDividers(
|
const filteredActions = visibilityFilteredActions.filter(
|
||||||
visibilityFilteredActions.filter(
|
(action) =>
|
||||||
(action) =>
|
typeof action.url !== 'function' ||
|
||||||
action.type === 'divider' ||
|
action.url(id) !== currentUrlWithoutActions
|
||||||
typeof action.url !== 'function' ||
|
|
||||||
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
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
|
||||||
@ -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
|
||||||
|
|||||||
@ -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,104 +237,92 @@ 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
|
<InputNumber
|
||||||
block
|
value={round(maxAcceleration, 2)}
|
||||||
size='small'
|
min={1}
|
||||||
style={{ flex: 1, minWidth: 0 }}
|
max={10000}
|
||||||
>
|
step={5}
|
||||||
<InputNumber
|
style={{ width: '125px' }}
|
||||||
value={round(maxAcceleration, 2)}
|
suffix='mm/s²'
|
||||||
min={1}
|
onChange={(value) => setMaxAcceleration(value)}
|
||||||
max={10000}
|
onPressEnter={handleSetMaxAcceleration}
|
||||||
step={5}
|
size='small'
|
||||||
style={controlInputStyle}
|
disabled={controlsDisabled}
|
||||||
suffix='mm/s²'
|
/>
|
||||||
onChange={(value) => setMaxAcceleration(value)}
|
<Button
|
||||||
onPressEnter={handleSetMaxAcceleration}
|
type='default'
|
||||||
size='small'
|
style={{ width: 40 }}
|
||||||
disabled={controlsDisabled}
|
onClick={handleSetMaxAcceleration}
|
||||||
/>
|
disabled={controlsDisabled}
|
||||||
<Button
|
>
|
||||||
type='default'
|
Set
|
||||||
style={{ width: 40 }}
|
</Button>
|
||||||
onClick={handleSetMaxAcceleration}
|
</Space.Compact>
|
||||||
disabled={controlsDisabled}
|
</Space>
|
||||||
>
|
</Space>
|
||||||
Set
|
|
||||||
</Button>
|
|
||||||
</Space.Compact>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<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
|
<InputNumber
|
||||||
block
|
value={round(squareCornerVelocity, 2) || 0}
|
||||||
size='small'
|
min={0.1}
|
||||||
style={{ flex: 1, minWidth: 0 }}
|
max={1000}
|
||||||
>
|
step={0.1}
|
||||||
<InputNumber
|
suffix='mm/s'
|
||||||
value={round(squareCornerVelocity, 2) || 0}
|
style={{ width: '125px' }}
|
||||||
min={0.1}
|
onChange={(value) => setSquareCornerVelocity(value)}
|
||||||
max={1000}
|
onPressEnter={handleSetSquareCornerVelocity}
|
||||||
step={0.1}
|
size='small'
|
||||||
style={controlInputStyle}
|
disabled={controlsDisabled}
|
||||||
suffix='mm/s'
|
/>
|
||||||
onChange={(value) => setSquareCornerVelocity(value)}
|
<Button
|
||||||
onPressEnter={handleSetSquareCornerVelocity}
|
type='default'
|
||||||
size='small'
|
style={{ width: 40 }}
|
||||||
disabled={controlsDisabled}
|
onClick={handleSetSquareCornerVelocity}
|
||||||
/>
|
disabled={controlsDisabled}
|
||||||
<Button
|
>
|
||||||
type='default'
|
Set
|
||||||
style={{ width: 40 }}
|
</Button>
|
||||||
onClick={handleSetSquareCornerVelocity}
|
</Space.Compact>
|
||||||
disabled={controlsDisabled}
|
</Space>
|
||||||
>
|
</Space>
|
||||||
Set
|
|
||||||
</Button>
|
|
||||||
</Space.Compact>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<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
|
<InputNumber
|
||||||
block
|
value={round(minCruiseRatio * 100, 2) || 0}
|
||||||
size='small'
|
min={0}
|
||||||
style={{ flex: 1, minWidth: 0 }}
|
max={100}
|
||||||
>
|
step={1}
|
||||||
<InputNumber
|
suffix='%'
|
||||||
value={round(minCruiseRatio * 100, 2) || 0}
|
style={{ width: '125px' }}
|
||||||
min={0}
|
onChange={(value) => setMinCruiseRatio(value / 100)}
|
||||||
max={100}
|
onPressEnter={handleSetMinCruiseRatio}
|
||||||
step={1}
|
size='small'
|
||||||
suffix='%'
|
disabled={controlsDisabled}
|
||||||
style={controlInputStyle}
|
/>
|
||||||
onChange={(value) => setMinCruiseRatio(value / 100)}
|
<Button
|
||||||
onPressEnter={handleSetMinCruiseRatio}
|
type='default'
|
||||||
size='small'
|
style={{ width: 40 }}
|
||||||
disabled={controlsDisabled}
|
onClick={handleSetMinCruiseRatio}
|
||||||
/>
|
disabled={controlsDisabled}
|
||||||
<Button
|
>
|
||||||
type='default'
|
Set
|
||||||
style={{ width: 40 }}
|
</Button>
|
||||||
onClick={handleSetMinCruiseRatio}
|
</Space.Compact>
|
||||||
disabled={controlsDisabled}
|
</Space>
|
||||||
>
|
</Space>
|
||||||
Set
|
</Space>
|
||||||
</Button>
|
|
||||||
</Space.Compact>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 || (
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user