@wandelbots/wandelbots-js-react-components 2.36.0 → 2.37.0-pr.feature-states-for-cycle-timer.379.b99a9af

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.
Files changed (44) hide show
  1. package/dist/components/CycleTimer/CycleTimer.d.ts +3 -0
  2. package/dist/components/CycleTimer/CycleTimer.d.ts.map +1 -0
  3. package/dist/components/CycleTimer/DefaultVariant.d.ts +10 -0
  4. package/dist/components/CycleTimer/DefaultVariant.d.ts.map +1 -0
  5. package/dist/components/CycleTimer/SmallVariant.d.ts +11 -0
  6. package/dist/components/CycleTimer/SmallVariant.d.ts.map +1 -0
  7. package/dist/components/CycleTimer/index.d.ts +28 -0
  8. package/dist/components/CycleTimer/index.d.ts.map +1 -0
  9. package/dist/components/CycleTimer/types.d.ts +51 -0
  10. package/dist/components/CycleTimer/types.d.ts.map +1 -0
  11. package/dist/components/CycleTimer/useAnimations.d.ts +15 -0
  12. package/dist/components/CycleTimer/useAnimations.d.ts.map +1 -0
  13. package/dist/components/CycleTimer/useTimerLogic.d.ts +26 -0
  14. package/dist/components/CycleTimer/useTimerLogic.d.ts.map +1 -0
  15. package/dist/components/CycleTimer/utils.d.ts +13 -0
  16. package/dist/components/CycleTimer/utils.d.ts.map +1 -0
  17. package/dist/components/CycleTimer.d.ts +2 -96
  18. package/dist/components/CycleTimer.d.ts.map +1 -1
  19. package/dist/components/TabBar.d.ts.map +1 -1
  20. package/dist/components/jogging/PoseCartesianValues.d.ts +8 -4
  21. package/dist/components/jogging/PoseCartesianValues.d.ts.map +1 -1
  22. package/dist/components/jogging/PoseJointValues.d.ts +8 -4
  23. package/dist/components/jogging/PoseJointValues.d.ts.map +1 -1
  24. package/dist/index.cjs +50 -50
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +9290 -8813
  27. package/dist/index.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/components/AppHeader.tsx +1 -1
  30. package/src/components/CycleTimer/CycleTimer.ts +6 -0
  31. package/src/components/CycleTimer/DefaultVariant.tsx +327 -0
  32. package/src/components/CycleTimer/SmallVariant.tsx +230 -0
  33. package/src/components/CycleTimer/index.tsx +157 -0
  34. package/src/components/CycleTimer/types.ts +60 -0
  35. package/src/components/CycleTimer/useAnimations.ts +202 -0
  36. package/src/components/CycleTimer/useTimerLogic.ts +386 -0
  37. package/src/components/CycleTimer/utils.ts +53 -0
  38. package/src/components/CycleTimer.tsx +6 -715
  39. package/src/components/ProgramControl.tsx +4 -4
  40. package/src/components/TabBar.tsx +8 -10
  41. package/src/components/jogging/PoseCartesianValues.tsx +67 -7
  42. package/src/components/jogging/PoseJointValues.tsx +68 -8
  43. package/src/i18n/locales/de/translations.json +4 -0
  44. package/src/i18n/locales/en/translations.json +4 -0
@@ -173,9 +173,9 @@ export const ProgramControl = externalizeComponent(
173
173
  }
174
174
  onClick={config.onClick}
175
175
  sx={{
176
- width: "110px",
177
- height: "110px",
178
- borderRadius: "110px",
176
+ width: "88px",
177
+ height: "88px",
178
+ borderRadius: "88px",
179
179
  backgroundColor: config.color,
180
180
  opacity:
181
181
  config.enabled &&
@@ -197,7 +197,7 @@ export const ProgramControl = externalizeComponent(
197
197
  backgroundColor: config.color,
198
198
  opacity: 0.3,
199
199
  },
200
- minWidth: "110px",
200
+ minWidth: "88px",
201
201
  flexShrink: 0,
202
202
  }}
203
203
  >
@@ -74,14 +74,13 @@ export const TabBar = externalizeComponent(
74
74
  sx={{ height: "100%", display: "flex", flexDirection: "column", ...sx }}
75
75
  >
76
76
  {/* Tabs */}
77
- <Box sx={{ px: 3, pt: 3, pb: 3 }}>
77
+ <Box sx={{ px: 0, py: 0 }}>
78
78
  <Tabs
79
79
  value={activeTab}
80
80
  onChange={handleTabChange}
81
81
  sx={{
82
- minHeight: "auto",
82
+ minHeight: "32px",
83
83
  backgroundColor: "transparent",
84
- mt: 3,
85
84
  "& .MuiTabs-indicator": {
86
85
  display: "none", // Hide the default indicator
87
86
  },
@@ -98,16 +97,15 @@ export const TabBar = externalizeComponent(
98
97
  iconPosition="start"
99
98
  disableRipple
100
99
  sx={{
101
- minHeight: "auto",
102
- minWidth: "auto",
103
- padding: "4px 8px",
104
- borderRadius: "10px",
100
+ minHeight: "32px",
101
+ height: "32px",
102
+ padding: "0px 10px",
103
+ borderRadius: "12px",
105
104
  backgroundColor: (theme) =>
106
105
  theme.palette.backgroundPaperElevation?.[11] || "#32344B",
107
106
  color: "text.primary",
108
107
  opacity: activeTab === index ? 1 : 0.38,
109
- textTransform: "none",
110
- fontWeight: 500,
108
+ fontSize: "13px",
111
109
  transition: "all 0.2s ease-in-out",
112
110
  "&:hover": {
113
111
  opacity: activeTab === index ? 1 : 0.6,
@@ -131,7 +129,7 @@ export const TabBar = externalizeComponent(
131
129
  </Box>
132
130
 
133
131
  {/* Border line */}
134
- <Box sx={{ mx: 3, borderBottom: 1, borderColor: "divider" }} />
132
+ <Box sx={{ mt: "32px", borderBottom: 1, borderColor: "divider" }} />
135
133
 
136
134
  {/* Tab Content */}
137
135
  <Box sx={{ flex: 1, overflow: "auto" }}>
@@ -1,21 +1,64 @@
1
- import { Stack } from "@mui/material"
1
+ import { Button, Stack, Typography } from "@mui/material"
2
2
  import { poseToWandelscriptString } from "@wandelbots/nova-js"
3
- import type { MotionStreamConnection } from "@wandelbots/nova-js/v1"
3
+ import type {
4
+ ConnectedMotionGroup,
5
+ MotionStreamConnection,
6
+ } from "@wandelbots/nova-js/v1"
4
7
  import { observer } from "mobx-react-lite"
5
- import { useRef } from "react"
8
+ import { useRef, useState } from "react"
6
9
  import { CopyableText } from "../CopyableText"
7
10
  import { useAnimationFrame } from "../utils/hooks"
8
11
 
12
+ export type PoseCartesianValuesProps = {
13
+ /** Either a MotionStreamConnection or ConnectedMotionGroup */
14
+ motionStream?: MotionStreamConnection
15
+ connectedMotionGroup?: ConnectedMotionGroup
16
+ showCopyButton?: boolean
17
+ }
18
+
9
19
  export const PoseCartesianValues = observer(
10
- ({ motionStream }: { motionStream: MotionStreamConnection }) => {
20
+ ({
21
+ motionStream,
22
+ connectedMotionGroup,
23
+ showCopyButton = false,
24
+ }: PoseCartesianValuesProps) => {
11
25
  const poseHolderRef = useRef<HTMLDivElement>(null)
26
+ const [copyMessage, setCopyMessage] = useState("")
27
+
28
+ // Use the provided motionStream or create a mock-like object from connectedMotionGroup
29
+ const activeMotionStream =
30
+ motionStream ||
31
+ (connectedMotionGroup
32
+ ? ({
33
+ rapidlyChangingMotionState:
34
+ connectedMotionGroup.rapidlyChangingMotionState,
35
+ } as MotionStreamConnection)
36
+ : undefined)
37
+
38
+ if (!activeMotionStream) {
39
+ throw new Error(
40
+ "PoseCartesianValues requires either motionStream or connectedMotionGroup prop",
41
+ )
42
+ }
12
43
 
13
44
  function getCurrentPoseString() {
14
- const tcpPose = motionStream.rapidlyChangingMotionState.tcp_pose
45
+ if (!activeMotionStream) return ""
46
+ const tcpPose = activeMotionStream.rapidlyChangingMotionState.tcp_pose
15
47
  if (!tcpPose) return ""
16
48
  return poseToWandelscriptString(tcpPose)
17
49
  }
18
50
 
51
+ const handleCopy = async () => {
52
+ try {
53
+ await navigator.clipboard.writeText(getCurrentPoseString())
54
+ setCopyMessage("Copied!")
55
+ setTimeout(() => setCopyMessage(""), 2000)
56
+ } catch {
57
+ setCopyMessage("Copy failed")
58
+ setTimeout(() => setCopyMessage(""), 2000)
59
+ }
60
+ }
61
+
19
62
  useAnimationFrame(() => {
20
63
  if (!poseHolderRef.current) {
21
64
  return
@@ -30,11 +73,28 @@ export const PoseCartesianValues = observer(
30
73
 
31
74
  return (
32
75
  <Stack
33
- alignItems="left"
34
- spacing={2}
76
+ direction="row"
77
+ alignItems="center"
78
+ spacing={1}
35
79
  sx={{ flexGrow: 1, minWidth: 0, overflow: "hidden" }}
36
80
  >
37
81
  <CopyableText value={getCurrentPoseString()} ref={poseHolderRef} />
82
+ {showCopyButton && (
83
+ <Button
84
+ variant="contained"
85
+ color="secondary"
86
+ size="small"
87
+ onClick={handleCopy}
88
+ sx={{ flexShrink: 0 }}
89
+ >
90
+ Copy
91
+ </Button>
92
+ )}
93
+ {copyMessage && (
94
+ <Typography variant="caption" color="success.main">
95
+ {copyMessage}
96
+ </Typography>
97
+ )}
38
98
  </Stack>
39
99
  )
40
100
  },
@@ -1,18 +1,61 @@
1
- import { Stack } from "@mui/material"
2
- import type { MotionStreamConnection } from "@wandelbots/nova-js/v1"
1
+ import { Button, Stack, Typography } from "@mui/material"
2
+ import type {
3
+ ConnectedMotionGroup,
4
+ MotionStreamConnection,
5
+ } from "@wandelbots/nova-js/v1"
3
6
  import { observer } from "mobx-react-lite"
4
- import { useRef } from "react"
7
+ import { useRef, useState } from "react"
5
8
  import { CopyableText } from "../CopyableText"
6
9
  import { useAnimationFrame } from "../utils/hooks"
7
10
 
11
+ export type PoseJointValuesProps = {
12
+ /** Either a MotionStreamConnection or ConnectedMotionGroup */
13
+ motionStream?: MotionStreamConnection
14
+ connectedMotionGroup?: ConnectedMotionGroup
15
+ showCopyButton?: boolean
16
+ }
17
+
8
18
  export const PoseJointValues = observer(
9
- ({ motionStream }: { motionStream: MotionStreamConnection }) => {
19
+ ({
20
+ motionStream,
21
+ connectedMotionGroup,
22
+ showCopyButton = false,
23
+ }: PoseJointValuesProps) => {
10
24
  const poseHolderRef = useRef<HTMLDivElement>(null)
25
+ const [copyMessage, setCopyMessage] = useState("")
26
+
27
+ // Use the provided motionStream or create a mock-like object from connectedMotionGroup
28
+ const activeMotionStream =
29
+ motionStream ||
30
+ (connectedMotionGroup
31
+ ? ({
32
+ rapidlyChangingMotionState:
33
+ connectedMotionGroup.rapidlyChangingMotionState,
34
+ } as MotionStreamConnection)
35
+ : undefined)
36
+
37
+ if (!activeMotionStream) {
38
+ throw new Error(
39
+ "PoseJointValues requires either motionStream or connectedMotionGroup prop",
40
+ )
41
+ }
11
42
 
12
43
  function getCurrentPoseString() {
44
+ if (!activeMotionStream) return ""
13
45
  const { joints } =
14
- motionStream.rapidlyChangingMotionState.state.joint_position
15
- return `[${joints.map((j) => parseFloat(j.toFixed(4))).join(", ")}]`
46
+ activeMotionStream.rapidlyChangingMotionState.state.joint_position
47
+ return `[${joints.map((j: number) => parseFloat(j.toFixed(4))).join(", ")}]`
48
+ }
49
+
50
+ const handleCopy = async () => {
51
+ try {
52
+ await navigator.clipboard.writeText(getCurrentPoseString())
53
+ setCopyMessage("Copied!")
54
+ setTimeout(() => setCopyMessage(""), 2000)
55
+ } catch {
56
+ setCopyMessage("Copy failed")
57
+ setTimeout(() => setCopyMessage(""), 2000)
58
+ }
16
59
  }
17
60
 
18
61
  useAnimationFrame(() => {
@@ -29,11 +72,28 @@ export const PoseJointValues = observer(
29
72
 
30
73
  return (
31
74
  <Stack
32
- alignItems="left"
33
- spacing={2}
75
+ direction="row"
76
+ alignItems="center"
77
+ spacing={1}
34
78
  sx={{ flexGrow: 1, minWidth: 0, overflow: "hidden" }}
35
79
  >
36
80
  <CopyableText value={getCurrentPoseString()} ref={poseHolderRef} />
81
+ {showCopyButton && (
82
+ <Button
83
+ variant="contained"
84
+ color="secondary"
85
+ size="small"
86
+ onClick={handleCopy}
87
+ sx={{ flexShrink: 0 }}
88
+ >
89
+ Copy
90
+ </Button>
91
+ )}
92
+ {copyMessage && (
93
+ <Typography variant="caption" color="success.main">
94
+ {copyMessage}
95
+ </Typography>
96
+ )}
37
97
  </Stack>
38
98
  )
39
99
  },
@@ -48,6 +48,10 @@
48
48
  "CycleTimer.OfTime.lb": "von {{time}} min.",
49
49
  "CycleTimer.Time.lb": "{{time}} min.",
50
50
  "CycleTimer.Error.lb": "Fehler",
51
+ "CycleTimer.WaitingForCycle.lb": "Warten auf Programmzyklus",
52
+ "CycleTimer.CycleTime.lb": "Zykluszeit",
53
+ "CycleTimer.Measuring.lb": "wird gemessen...",
54
+ "CycleTimer.Determined.lb": "bestimmt",
51
55
  "ProgramControl.Start.bt": "Start",
52
56
  "ProgramControl.Resume.bt": "Weiter",
53
57
  "ProgramControl.Retry.bt": "Wiederholen",
@@ -49,6 +49,10 @@
49
49
  "CycleTimer.OfTime.lb": "of {{time}} min.",
50
50
  "CycleTimer.Time.lb": "{{time}} min.",
51
51
  "CycleTimer.Error.lb": "Error",
52
+ "CycleTimer.WaitingForCycle.lb": "Waiting for program cycle",
53
+ "CycleTimer.CycleTime.lb": "Cycle Time",
54
+ "CycleTimer.Measuring.lb": "measuring...",
55
+ "CycleTimer.Determined.lb": "determined",
52
56
  "ProgramControl.Start.bt": "Start",
53
57
  "ProgramControl.Resume.bt": "Resume",
54
58
  "ProgramControl.Retry.bt": "Retry",