@knime/hub-features 1.21.1 → 1.21.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @knime/hub-features
2
2
 
3
+ ## 1.21.2
4
+
5
+ ### Patch Changes
6
+
7
+ - bfe6ec3: NXT-4509: add custom clipboard serialization to RFCError toast
8
+
3
9
  ## 1.21.1
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knime/hub-features",
3
- "version": "1.21.1",
3
+ "version": "1.21.2",
4
4
  "description": "Vue components & composables for shared hub features",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,8 +37,8 @@
37
37
  "ofetch": "^1.4.1",
38
38
  "typescript": "^5.9.3",
39
39
  "@knime/components": "1.45.7",
40
- "@knime/styles": "1.15.0",
41
- "@knime/utils": "1.10.0"
40
+ "@knime/utils": "1.10.0",
41
+ "@knime/styles": "1.15.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "consola": "3.x",
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref } from "vue";
2
+ import { ref } from "vue";
3
3
  import { useClipboard } from "@vueuse/core";
4
4
 
5
5
  import { Button } from "@knime/components";
@@ -7,11 +7,17 @@ import CheckIcon from "@knime/styles/img/icons/check.svg";
7
7
  import CopyIcon from "@knime/styles/img/icons/copy.svg";
8
8
  import { formatDateTimeString } from "@knime/utils";
9
9
 
10
+ import { serializeErrorForClipboard as defaultSerializeRFCErrorData } from "./serializeRFCErrorData";
10
11
  import type { RFCErrorData } from "./types";
11
12
 
12
13
  type Props = {
13
14
  headline: string; // toast headline, will not be displayed here but needed when copying to clipboard
14
15
  canCopyToClipboard?: boolean;
16
+ serializeErrorForClipboard?: (
17
+ error: RFCErrorData,
18
+ headline: string,
19
+ formatDate: (date: Date) => string,
20
+ ) => string;
15
21
  } & RFCErrorData;
16
22
 
17
23
  const props = withDefaults(defineProps<Props>(), {
@@ -21,6 +27,7 @@ const props = withDefaults(defineProps<Props>(), {
21
27
  requestId: undefined,
22
28
  errorId: undefined,
23
29
  canCopyToClipboard: true,
30
+ serializeErrorForClipboard: defaultSerializeRFCErrorData,
24
31
  });
25
32
  const emits = defineEmits(["showMore"]);
26
33
 
@@ -30,53 +37,13 @@ const { copy, copied } = useClipboard({
30
37
 
31
38
  const showDetails = ref(false);
32
39
 
33
- const formattedDate = computed(() => {
34
- return props.date ? formatDateTimeString(props.date.getTime()) : "";
35
- });
36
-
37
- const errorForClipboard = computed(() => {
38
- let details = "";
39
- if (props.details?.length) {
40
- if (props.details.length > 1) {
41
- const detailLines = props.details
42
- .map((item) => `\u2022 ${item}`)
43
- .join("\n");
44
- details = `\n${detailLines}`;
45
- } else {
46
- details = props.details[0];
47
- }
48
- }
49
-
50
- let errorText = `${props.headline}\n\n`;
51
- errorText += `${props.title}\n\n`;
52
- errorText += details ? `Details: ${details}\n\n` : "";
53
-
54
- if (props.status !== undefined) {
55
- errorText += `Status: ${props.status}\n`;
56
- }
57
-
58
- if (props.date) {
59
- errorText += `Date: ${formattedDate.value}\n`;
60
- }
61
-
62
- if (props.requestId) {
63
- errorText += `Request Id: ${props.requestId}\n`;
64
- }
65
-
66
- if (props.errorId) {
67
- errorText += `Error Id: ${props.errorId}\n`;
68
- }
69
-
70
- if (props.stacktrace) {
71
- errorText += "------\n"; // separator
72
- errorText += `Stacktrace:\n\n${props.stacktrace}\n`;
73
- }
74
-
75
- return errorText;
76
- });
40
+ const formatDate = (date: Date): string =>
41
+ date ? formatDateTimeString(date.getTime()) : "";
77
42
 
78
43
  const copyToClipboard = () => {
79
- copy(errorForClipboard.value).catch((error) => {
44
+ copy(
45
+ props.serializeErrorForClipboard(props, props.headline, formatDate),
46
+ ).catch((error) => {
80
47
  consola.error("Failed to copy to clipboard", { error });
81
48
  });
82
49
  };
@@ -116,7 +83,7 @@ const onShowDetailsClicked = () => {
116
83
  <div v-if="status !== undefined">
117
84
  <strong>Status: </strong>{{ status }}
118
85
  </div>
119
- <div v-if="date"><strong>Date: </strong>{{ formattedDate }}</div>
86
+ <div v-if="date"><strong>Date: </strong>{{ formatDate(date) }}</div>
120
87
  <div v-if="requestId"><strong>Request id: </strong>{{ requestId }}</div>
121
88
  <div v-if="errorId"><strong>Error id: </strong>{{ errorId }}</div>
122
89
  <div v-if="stacktrace && canCopyToClipboard">
@@ -13,10 +13,16 @@ const toToast = ({
13
13
  headline,
14
14
  rfcError,
15
15
  canCopyToClipboard = true,
16
+ serializeErrorForClipboard = undefined,
16
17
  }: {
17
18
  headline: string;
18
19
  rfcError: RFCError;
19
20
  canCopyToClipboard?: boolean;
21
+ serializeErrorForClipboard?: (
22
+ error: RFCErrorData,
23
+ headline: string,
24
+ formatDate: (date: Date) => string,
25
+ ) => string;
20
26
  }): Toast => {
21
27
  const { data } = rfcError;
22
28
 
@@ -24,6 +30,7 @@ const toToast = ({
24
30
  headline,
25
31
  ...data,
26
32
  canCopyToClipboard,
33
+ serializeErrorForClipboard,
27
34
  });
28
35
 
29
36
  return {
@@ -0,0 +1,46 @@
1
+ import type { RFCErrorData } from "./types";
2
+
3
+ export const serializeErrorForClipboard = (
4
+ error: RFCErrorData,
5
+ headline: string,
6
+ formatDate: (date: Date) => string,
7
+ ): string => {
8
+ let details = "";
9
+ if (error.details?.length) {
10
+ if (error.details.length > 1) {
11
+ const detailLines = error.details
12
+ .map((item) => `\u2022 ${item}`)
13
+ .join("\n");
14
+ details = `\n${detailLines}`;
15
+ } else {
16
+ details = error.details[0];
17
+ }
18
+ }
19
+
20
+ let errorText = `${headline}\n\n`;
21
+ errorText += `${error.title}\n\n`;
22
+ errorText += details ? `Details: ${details}\n\n` : "";
23
+
24
+ if (error.status !== undefined) {
25
+ errorText += `Status: ${error.status}\n`;
26
+ }
27
+
28
+ if (error.date) {
29
+ errorText += `Date: ${formatDate(error.date)}\n`;
30
+ }
31
+
32
+ if (error.requestId) {
33
+ errorText += `Request Id: ${error.requestId}\n`;
34
+ }
35
+
36
+ if (error.errorId) {
37
+ errorText += `Error Id: ${error.errorId}\n`;
38
+ }
39
+
40
+ if (error.stacktrace) {
41
+ errorText += "------\n"; // separator
42
+ errorText += `Stacktrace:\n\n${error.stacktrace}\n`;
43
+ }
44
+
45
+ return errorText;
46
+ };