@wandelbots/wandelbots-js-react-components 2.37.0 → 2.38.0

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 (40) 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/jogging/PoseCartesianValues.d.ts +8 -4
  20. package/dist/components/jogging/PoseCartesianValues.d.ts.map +1 -1
  21. package/dist/components/jogging/PoseJointValues.d.ts +8 -4
  22. package/dist/components/jogging/PoseJointValues.d.ts.map +1 -1
  23. package/dist/index.cjs +50 -50
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +9299 -8800
  26. package/dist/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/components/CycleTimer/CycleTimer.ts +6 -0
  29. package/src/components/CycleTimer/DefaultVariant.tsx +327 -0
  30. package/src/components/CycleTimer/SmallVariant.tsx +230 -0
  31. package/src/components/CycleTimer/index.tsx +157 -0
  32. package/src/components/CycleTimer/types.ts +60 -0
  33. package/src/components/CycleTimer/useAnimations.ts +202 -0
  34. package/src/components/CycleTimer/useTimerLogic.ts +386 -0
  35. package/src/components/CycleTimer/utils.ts +53 -0
  36. package/src/components/CycleTimer.tsx +6 -715
  37. package/src/components/jogging/PoseCartesianValues.tsx +85 -7
  38. package/src/components/jogging/PoseJointValues.tsx +86 -8
  39. package/src/i18n/locales/de/translations.json +4 -0
  40. package/src/i18n/locales/en/translations.json +4 -0
@@ -1,21 +1,82 @@
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
+ MotionGroupStateResponse,
6
+ MotionStreamConnection,
7
+ } from "@wandelbots/nova-js/v1"
4
8
  import { observer } from "mobx-react-lite"
5
- import { useRef } from "react"
9
+ import { useRef, useState } from "react"
6
10
  import { CopyableText } from "../CopyableText"
7
11
  import { useAnimationFrame } from "../utils/hooks"
8
12
 
13
+ /** Minimal interface for what PoseCartesianValues needs from motion stream */
14
+ type MotionStateProvider = {
15
+ rapidlyChangingMotionState: MotionGroupStateResponse
16
+ }
17
+
18
+ /** Creates a motion state provider from either a MotionStreamConnection or ConnectedMotionGroup */
19
+ function createMotionStateProvider(
20
+ motionStream?: MotionStreamConnection,
21
+ connectedMotionGroup?: ConnectedMotionGroup,
22
+ ): MotionStateProvider | undefined {
23
+ if (motionStream) {
24
+ return motionStream
25
+ }
26
+ if (connectedMotionGroup) {
27
+ return {
28
+ rapidlyChangingMotionState:
29
+ connectedMotionGroup.rapidlyChangingMotionState,
30
+ }
31
+ }
32
+ return undefined
33
+ }
34
+
35
+ export type PoseCartesianValuesProps = {
36
+ /** Either a MotionStreamConnection or ConnectedMotionGroup */
37
+ motionStream?: MotionStreamConnection
38
+ connectedMotionGroup?: ConnectedMotionGroup
39
+ showCopyButton?: boolean
40
+ }
41
+
9
42
  export const PoseCartesianValues = observer(
10
- ({ motionStream }: { motionStream: MotionStreamConnection }) => {
43
+ ({
44
+ motionStream,
45
+ connectedMotionGroup,
46
+ showCopyButton = false,
47
+ }: PoseCartesianValuesProps) => {
11
48
  const poseHolderRef = useRef<HTMLDivElement>(null)
49
+ const [copyMessage, setCopyMessage] = useState("")
50
+
51
+ const activeMotionStream = createMotionStateProvider(
52
+ motionStream,
53
+ connectedMotionGroup,
54
+ )
55
+
56
+ if (!activeMotionStream) {
57
+ throw new Error(
58
+ "PoseCartesianValues requires either motionStream or connectedMotionGroup prop",
59
+ )
60
+ }
12
61
 
13
62
  function getCurrentPoseString() {
14
- const tcpPose = motionStream.rapidlyChangingMotionState.tcp_pose
63
+ if (!activeMotionStream) return ""
64
+ const tcpPose = activeMotionStream.rapidlyChangingMotionState.tcp_pose
15
65
  if (!tcpPose) return ""
16
66
  return poseToWandelscriptString(tcpPose)
17
67
  }
18
68
 
69
+ const handleCopy = async () => {
70
+ try {
71
+ await navigator.clipboard.writeText(getCurrentPoseString())
72
+ setCopyMessage("Copied!")
73
+ setTimeout(() => setCopyMessage(""), 2000)
74
+ } catch {
75
+ setCopyMessage("Copy failed")
76
+ setTimeout(() => setCopyMessage(""), 2000)
77
+ }
78
+ }
79
+
19
80
  useAnimationFrame(() => {
20
81
  if (!poseHolderRef.current) {
21
82
  return
@@ -30,11 +91,28 @@ export const PoseCartesianValues = observer(
30
91
 
31
92
  return (
32
93
  <Stack
33
- alignItems="left"
34
- spacing={2}
94
+ direction="row"
95
+ alignItems="center"
96
+ spacing={1}
35
97
  sx={{ flexGrow: 1, minWidth: 0, overflow: "hidden" }}
36
98
  >
37
99
  <CopyableText value={getCurrentPoseString()} ref={poseHolderRef} />
100
+ {showCopyButton && (
101
+ <Button
102
+ variant="contained"
103
+ color="secondary"
104
+ size="small"
105
+ onClick={handleCopy}
106
+ sx={{ flexShrink: 0 }}
107
+ >
108
+ Copy
109
+ </Button>
110
+ )}
111
+ {copyMessage && (
112
+ <Typography variant="caption" color="success.main">
113
+ {copyMessage}
114
+ </Typography>
115
+ )}
38
116
  </Stack>
39
117
  )
40
118
  },
@@ -1,18 +1,79 @@
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
+ MotionGroupStateResponse,
5
+ MotionStreamConnection,
6
+ } from "@wandelbots/nova-js/v1"
3
7
  import { observer } from "mobx-react-lite"
4
- import { useRef } from "react"
8
+ import { useRef, useState } from "react"
5
9
  import { CopyableText } from "../CopyableText"
6
10
  import { useAnimationFrame } from "../utils/hooks"
7
11
 
12
+ /** Minimal interface for what PoseJointValues needs from motion stream */
13
+ type MotionStateProvider = {
14
+ rapidlyChangingMotionState: MotionGroupStateResponse
15
+ }
16
+
17
+ /** Creates a motion state provider from either a MotionStreamConnection or ConnectedMotionGroup */
18
+ function createMotionStateProvider(
19
+ motionStream?: MotionStreamConnection,
20
+ connectedMotionGroup?: ConnectedMotionGroup,
21
+ ): MotionStateProvider | undefined {
22
+ if (motionStream) {
23
+ return motionStream
24
+ }
25
+ if (connectedMotionGroup) {
26
+ return {
27
+ rapidlyChangingMotionState:
28
+ connectedMotionGroup.rapidlyChangingMotionState,
29
+ }
30
+ }
31
+ return undefined
32
+ }
33
+
34
+ export type PoseJointValuesProps = {
35
+ /** Either a MotionStreamConnection or ConnectedMotionGroup */
36
+ motionStream?: MotionStreamConnection
37
+ connectedMotionGroup?: ConnectedMotionGroup
38
+ showCopyButton?: boolean
39
+ }
40
+
8
41
  export const PoseJointValues = observer(
9
- ({ motionStream }: { motionStream: MotionStreamConnection }) => {
42
+ ({
43
+ motionStream,
44
+ connectedMotionGroup,
45
+ showCopyButton = false,
46
+ }: PoseJointValuesProps) => {
10
47
  const poseHolderRef = useRef<HTMLDivElement>(null)
48
+ const [copyMessage, setCopyMessage] = useState("")
49
+
50
+ const activeMotionStream = createMotionStateProvider(
51
+ motionStream,
52
+ connectedMotionGroup,
53
+ )
54
+
55
+ if (!activeMotionStream) {
56
+ throw new Error(
57
+ "PoseJointValues requires either motionStream or connectedMotionGroup prop",
58
+ )
59
+ }
11
60
 
12
61
  function getCurrentPoseString() {
62
+ if (!activeMotionStream) return ""
13
63
  const { joints } =
14
- motionStream.rapidlyChangingMotionState.state.joint_position
15
- return `[${joints.map((j) => parseFloat(j.toFixed(4))).join(", ")}]`
64
+ activeMotionStream.rapidlyChangingMotionState.state.joint_position
65
+ return `[${joints.map((j: number) => parseFloat(j.toFixed(4))).join(", ")}]`
66
+ }
67
+
68
+ const handleCopy = async () => {
69
+ try {
70
+ await navigator.clipboard.writeText(getCurrentPoseString())
71
+ setCopyMessage("Copied!")
72
+ setTimeout(() => setCopyMessage(""), 2000)
73
+ } catch {
74
+ setCopyMessage("Copy failed")
75
+ setTimeout(() => setCopyMessage(""), 2000)
76
+ }
16
77
  }
17
78
 
18
79
  useAnimationFrame(() => {
@@ -29,11 +90,28 @@ export const PoseJointValues = observer(
29
90
 
30
91
  return (
31
92
  <Stack
32
- alignItems="left"
33
- spacing={2}
93
+ direction="row"
94
+ alignItems="center"
95
+ spacing={1}
34
96
  sx={{ flexGrow: 1, minWidth: 0, overflow: "hidden" }}
35
97
  >
36
98
  <CopyableText value={getCurrentPoseString()} ref={poseHolderRef} />
99
+ {showCopyButton && (
100
+ <Button
101
+ variant="contained"
102
+ color="secondary"
103
+ size="small"
104
+ onClick={handleCopy}
105
+ sx={{ flexShrink: 0 }}
106
+ >
107
+ Copy
108
+ </Button>
109
+ )}
110
+ {copyMessage && (
111
+ <Typography variant="caption" color="success.main">
112
+ {copyMessage}
113
+ </Typography>
114
+ )}
37
115
  </Stack>
38
116
  )
39
117
  },
@@ -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",