@wandelbots/wandelbots-js-react-components 2.38.1-pr.feature-remove-timer-from-robot-card.381.54703fe → 2.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/RobotCard.d.ts +30 -24
- package/dist/components/RobotCard.d.ts.map +1 -1
- package/dist/index.cjs +41 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1844 -1800
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/CycleTimer/DefaultVariant.tsx +3 -3
- package/src/components/CycleTimer/useTimerLogic.ts +2 -2
- package/src/components/RobotCard.tsx +126 -49
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "2.38.1
|
|
3
|
+
"version": "2.38.1",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -117,7 +117,7 @@ export const DefaultVariant = ({
|
|
|
117
117
|
currentState !== "countup" &&
|
|
118
118
|
currentState !== "success"
|
|
119
119
|
}
|
|
120
|
-
timeout={
|
|
120
|
+
timeout={200}
|
|
121
121
|
>
|
|
122
122
|
<Typography
|
|
123
123
|
variant="body2"
|
|
@@ -237,7 +237,7 @@ export const DefaultVariant = ({
|
|
|
237
237
|
currentState !== "idle" &&
|
|
238
238
|
currentState !== "success"
|
|
239
239
|
}
|
|
240
|
-
timeout={
|
|
240
|
+
timeout={200}
|
|
241
241
|
>
|
|
242
242
|
<Typography
|
|
243
243
|
variant="h1"
|
|
@@ -280,7 +280,7 @@ export const DefaultVariant = ({
|
|
|
280
280
|
currentState !== "countup" &&
|
|
281
281
|
currentState !== "success"
|
|
282
282
|
}
|
|
283
|
-
timeout={
|
|
283
|
+
timeout={200}
|
|
284
284
|
>
|
|
285
285
|
<Typography
|
|
286
286
|
variant="body2"
|
|
@@ -53,10 +53,10 @@ export const useTimerLogic = ({
|
|
|
53
53
|
...prev,
|
|
54
54
|
currentState: "idle",
|
|
55
55
|
maxTime: null,
|
|
56
|
-
|
|
56
|
+
remainingTime: 0,
|
|
57
57
|
isRunning: false,
|
|
58
58
|
isPausedState: false,
|
|
59
|
-
currentProgress: 0, //
|
|
59
|
+
currentProgress: 0, // Immediately reset progress to 0
|
|
60
60
|
}))
|
|
61
61
|
pausedTimeRef.current = 0
|
|
62
62
|
startTimeRef.current = null
|
|
@@ -12,6 +12,7 @@ import { useTranslation } from "react-i18next"
|
|
|
12
12
|
import type { Group } from "three"
|
|
13
13
|
import { externalizeComponent } from "../externalizeComponent"
|
|
14
14
|
import { PresetEnvironment } from "./3d-viewport/PresetEnvironment"
|
|
15
|
+
import { CycleTimer } from "./CycleTimer"
|
|
15
16
|
import type { ProgramState } from "./ProgramControl"
|
|
16
17
|
import { ProgramStateIndicator } from "./ProgramStateIndicator"
|
|
17
18
|
import { Robot } from "./robots/Robot"
|
|
@@ -57,8 +58,34 @@ export interface RobotCardProps {
|
|
|
57
58
|
transparentColor?: string
|
|
58
59
|
getModel?: (modelFromController: string) => string
|
|
59
60
|
}>
|
|
60
|
-
/** Custom
|
|
61
|
-
|
|
61
|
+
/** Custom cycle timer component (optional, defaults to CycleTimer) */
|
|
62
|
+
cycleTimerComponent?: React.ComponentType<{
|
|
63
|
+
variant?: "default" | "small"
|
|
64
|
+
compact?: boolean
|
|
65
|
+
onCycleComplete: (controls: {
|
|
66
|
+
startNewCycle: (maxTimeSeconds?: number, elapsedSeconds?: number) => void
|
|
67
|
+
pause: () => void
|
|
68
|
+
resume: () => void
|
|
69
|
+
isPaused: () => boolean
|
|
70
|
+
}) => void
|
|
71
|
+
onCycleEnd?: () => void
|
|
72
|
+
autoStart?: boolean
|
|
73
|
+
hasError?: boolean
|
|
74
|
+
className?: string
|
|
75
|
+
}>
|
|
76
|
+
/** Callback to receive cycle timer controls for external timer management */
|
|
77
|
+
onCycleTimerReady?: (controls: {
|
|
78
|
+
startNewCycle: (maxTimeSeconds?: number, elapsedSeconds?: number) => void
|
|
79
|
+
pause: () => void
|
|
80
|
+
resume: () => void
|
|
81
|
+
isPaused: () => boolean
|
|
82
|
+
}) => void
|
|
83
|
+
/** Callback fired when a cycle completes (reaches zero) */
|
|
84
|
+
onCycleEnd?: () => void
|
|
85
|
+
/** Whether the cycle timer should auto-start when a new cycle is set */
|
|
86
|
+
cycleTimerAutoStart?: boolean
|
|
87
|
+
/** Whether the cycle timer is in an error state (pauses timer and shows error styling) */
|
|
88
|
+
cycleTimerHasError?: boolean
|
|
62
89
|
/** Additional CSS class name */
|
|
63
90
|
className?: string
|
|
64
91
|
}
|
|
@@ -81,31 +108,11 @@ export interface RobotCardProps {
|
|
|
81
108
|
* - Robot name displayed in Typography h6 at top-left
|
|
82
109
|
* - Program state indicator below the name
|
|
83
110
|
* - Auto-fitting 3D robot model that scales with container size
|
|
84
|
-
* -
|
|
111
|
+
* - Compact cycle time component with small variant, error state, and count-up/count-down mode support
|
|
85
112
|
* - Transparent gray divider line
|
|
86
113
|
* - "Drive to Home" button with press-and-hold functionality
|
|
87
114
|
* - Localization support via react-i18next
|
|
88
115
|
* - Material-UI theming integration
|
|
89
|
-
*
|
|
90
|
-
* Usage with custom content:
|
|
91
|
-
* ```tsx
|
|
92
|
-
* // Example custom timer component
|
|
93
|
-
* const CustomTimer = () => (
|
|
94
|
-
* <Box>
|
|
95
|
-
* <Typography variant="body1" sx={{ color: "text.secondary" }}>
|
|
96
|
-
* Runtime
|
|
97
|
-
* </Typography>
|
|
98
|
-
* <Typography variant="h6">05:23</Typography>
|
|
99
|
-
* </Box>
|
|
100
|
-
* )
|
|
101
|
-
*
|
|
102
|
-
* <RobotCard
|
|
103
|
-
* robotName="UR5e Robot"
|
|
104
|
-
* programState={ProgramState.RUNNING}
|
|
105
|
-
* customContentComponent={CustomTimer}
|
|
106
|
-
* // ... other props
|
|
107
|
-
* />
|
|
108
|
-
* ```
|
|
109
116
|
*/
|
|
110
117
|
export const RobotCard = externalizeComponent(
|
|
111
118
|
observer(
|
|
@@ -119,7 +126,11 @@ export const RobotCard = externalizeComponent(
|
|
|
119
126
|
onDriveToHomeRelease,
|
|
120
127
|
connectedMotionGroup,
|
|
121
128
|
robotComponent: RobotComponent = Robot,
|
|
122
|
-
|
|
129
|
+
cycleTimerComponent: CycleTimerComponent = CycleTimer,
|
|
130
|
+
onCycleTimerReady,
|
|
131
|
+
onCycleEnd,
|
|
132
|
+
cycleTimerAutoStart = true,
|
|
133
|
+
cycleTimerHasError = false,
|
|
123
134
|
className,
|
|
124
135
|
}: RobotCardProps) => {
|
|
125
136
|
const theme = useTheme()
|
|
@@ -134,6 +145,17 @@ export const RobotCard = externalizeComponent(
|
|
|
134
145
|
}>({ width: 400, height: 600 })
|
|
135
146
|
const [modelRenderTrigger, setModelRenderTrigger] = useState(0)
|
|
136
147
|
|
|
148
|
+
// Store cycle timer controls for external control
|
|
149
|
+
const cycleControlsRef = useRef<{
|
|
150
|
+
startNewCycle: (
|
|
151
|
+
maxTimeSeconds?: number,
|
|
152
|
+
elapsedSeconds?: number,
|
|
153
|
+
) => void
|
|
154
|
+
pause: () => void
|
|
155
|
+
resume: () => void
|
|
156
|
+
isPaused: () => boolean
|
|
157
|
+
} | null>(null)
|
|
158
|
+
|
|
137
159
|
// Hook to detect aspect ratio and size changes
|
|
138
160
|
useEffect(() => {
|
|
139
161
|
const checkDimensions = () => {
|
|
@@ -182,16 +204,38 @@ export const RobotCard = externalizeComponent(
|
|
|
182
204
|
}
|
|
183
205
|
}, [isDriveToHomePressed, onDriveToHomeRelease])
|
|
184
206
|
|
|
207
|
+
// Store and provide cycle timer controls for external use
|
|
208
|
+
const handleCycleComplete = useCallback(
|
|
209
|
+
(controls: {
|
|
210
|
+
startNewCycle: (
|
|
211
|
+
maxTimeSeconds?: number,
|
|
212
|
+
elapsedSeconds?: number,
|
|
213
|
+
) => void
|
|
214
|
+
pause: () => void
|
|
215
|
+
resume: () => void
|
|
216
|
+
isPaused: () => boolean
|
|
217
|
+
}) => {
|
|
218
|
+
// Store the controls for potential future use
|
|
219
|
+
cycleControlsRef.current = controls
|
|
220
|
+
|
|
221
|
+
// Notify parent component that timer controls are ready
|
|
222
|
+
if (onCycleTimerReady) {
|
|
223
|
+
onCycleTimerReady(controls)
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
[onCycleTimerReady],
|
|
227
|
+
)
|
|
228
|
+
|
|
185
229
|
// Determine if robot should be hidden at small sizes to save space
|
|
186
230
|
const shouldHideRobot = isLandscape
|
|
187
231
|
? cardSize.width < 350
|
|
188
232
|
: cardSize.height < 200 // Hide robot at height < 200px in portrait
|
|
189
233
|
|
|
190
|
-
// Determine if
|
|
191
|
-
//
|
|
192
|
-
const
|
|
193
|
-
? cardSize.height < 310 // Landscape: hide
|
|
194
|
-
: cardSize.height < 450 // Portrait: hide
|
|
234
|
+
// Determine if runtime view should be hidden when height is too low
|
|
235
|
+
// Runtime should be hidden BEFORE the robot (at higher threshold)
|
|
236
|
+
const shouldHideRuntime = isLandscape
|
|
237
|
+
? cardSize.height < 310 // Landscape: hide runtime at height < 350px
|
|
238
|
+
: cardSize.height < 450 // Portrait: hide runtime at height < 450px
|
|
195
239
|
|
|
196
240
|
return (
|
|
197
241
|
<Card
|
|
@@ -293,7 +337,7 @@ export const RobotCard = externalizeComponent(
|
|
|
293
337
|
/>
|
|
294
338
|
</Box>
|
|
295
339
|
|
|
296
|
-
{/* Bottom section with
|
|
340
|
+
{/* Bottom section with runtime, cycle time, and button */}
|
|
297
341
|
<Box
|
|
298
342
|
sx={{
|
|
299
343
|
p: { xs: 1.5, sm: 2, md: 3 },
|
|
@@ -304,10 +348,32 @@ export const RobotCard = externalizeComponent(
|
|
|
304
348
|
justifyContent: "space-between",
|
|
305
349
|
}}
|
|
306
350
|
>
|
|
307
|
-
{/*
|
|
308
|
-
{!
|
|
351
|
+
{/* Runtime view - hidden if height is too low in landscape mode */}
|
|
352
|
+
{!shouldHideRuntime && (
|
|
309
353
|
<Box>
|
|
310
|
-
|
|
354
|
+
{/* Runtime display */}
|
|
355
|
+
<Typography
|
|
356
|
+
variant="body1"
|
|
357
|
+
sx={{
|
|
358
|
+
mb: 0,
|
|
359
|
+
color: theme.palette.text.secondary,
|
|
360
|
+
textAlign: "left",
|
|
361
|
+
}}
|
|
362
|
+
>
|
|
363
|
+
{t("RobotCard.Runtime.lb")}
|
|
364
|
+
</Typography>
|
|
365
|
+
|
|
366
|
+
{/* Compact cycle time component directly below runtime */}
|
|
367
|
+
<Box sx={{ textAlign: "left" }}>
|
|
368
|
+
<CycleTimerComponent
|
|
369
|
+
variant="small"
|
|
370
|
+
compact
|
|
371
|
+
onCycleComplete={handleCycleComplete}
|
|
372
|
+
onCycleEnd={onCycleEnd}
|
|
373
|
+
autoStart={cycleTimerAutoStart}
|
|
374
|
+
hasError={cycleTimerHasError}
|
|
375
|
+
/>
|
|
376
|
+
</Box>
|
|
311
377
|
|
|
312
378
|
{/* Divider */}
|
|
313
379
|
<Divider
|
|
@@ -321,14 +387,7 @@ export const RobotCard = externalizeComponent(
|
|
|
321
387
|
</Box>
|
|
322
388
|
)}
|
|
323
389
|
|
|
324
|
-
<Box
|
|
325
|
-
sx={{
|
|
326
|
-
mt:
|
|
327
|
-
!shouldHideCustomContent && CustomContentComponent
|
|
328
|
-
? "auto"
|
|
329
|
-
: 0,
|
|
330
|
-
}}
|
|
331
|
-
>
|
|
390
|
+
<Box sx={{ mt: !shouldHideRuntime ? "auto" : 0 }}>
|
|
332
391
|
{/* Drive to Home button with some space */}
|
|
333
392
|
<Box
|
|
334
393
|
sx={{
|
|
@@ -429,12 +488,31 @@ export const RobotCard = externalizeComponent(
|
|
|
429
488
|
)}
|
|
430
489
|
</Box>
|
|
431
490
|
|
|
432
|
-
{/* Bottom section with
|
|
491
|
+
{/* Bottom section with runtime, cycle time, and button */}
|
|
433
492
|
<Box>
|
|
434
|
-
{/*
|
|
435
|
-
{!
|
|
493
|
+
{/* Runtime view - hidden if height is too low */}
|
|
494
|
+
{!shouldHideRuntime && (
|
|
436
495
|
<>
|
|
437
|
-
|
|
496
|
+
{/* Runtime display */}
|
|
497
|
+
<Typography
|
|
498
|
+
variant="body1"
|
|
499
|
+
sx={{
|
|
500
|
+
mb: 0,
|
|
501
|
+
color: theme.palette.text.secondary,
|
|
502
|
+
}}
|
|
503
|
+
>
|
|
504
|
+
{t("RobotCard.Runtime.lb")}
|
|
505
|
+
</Typography>
|
|
506
|
+
|
|
507
|
+
{/* Compact cycle time component directly below runtime */}
|
|
508
|
+
<CycleTimerComponent
|
|
509
|
+
variant="small"
|
|
510
|
+
compact
|
|
511
|
+
onCycleComplete={handleCycleComplete}
|
|
512
|
+
onCycleEnd={onCycleEnd}
|
|
513
|
+
autoStart={cycleTimerAutoStart}
|
|
514
|
+
hasError={cycleTimerHasError}
|
|
515
|
+
/>
|
|
438
516
|
|
|
439
517
|
{/* Divider */}
|
|
440
518
|
<Divider
|
|
@@ -453,10 +531,9 @@ export const RobotCard = externalizeComponent(
|
|
|
453
531
|
sx={{
|
|
454
532
|
display: "flex",
|
|
455
533
|
justifyContent: "flex-start",
|
|
456
|
-
mt:
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
: { xs: 0.5, sm: 1, md: 2 },
|
|
534
|
+
mt: !shouldHideRuntime
|
|
535
|
+
? { xs: 1, sm: 2, md: 5 }
|
|
536
|
+
: { xs: 0.5, sm: 1, md: 2 },
|
|
460
537
|
mb: { xs: 0.5, sm: 0.75, md: 1 },
|
|
461
538
|
}}
|
|
462
539
|
>
|