@cccsaurora/clue-ui 1.2.0-dev.177 → 1.2.0-dev.182

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 (41) hide show
  1. package/{ActionForm-BenaoSSk.js → ActionForm-xoGOCx0G.js} +29 -11
  2. package/{AnnotationDetails-CbXSCkTF.js → AnnotationDetails-Dbatv1yI.js} +1 -1
  3. package/{AnnotationPreview-D5NX8_su.js → AnnotationPreview-BFPdQYFa.js} +1 -1
  4. package/components/AnnotationDetailPopover.js +1 -1
  5. package/components/AnnotationDetails.js +2 -2
  6. package/components/AnnotationPreview.js +1 -1
  7. package/components/EnrichedCard.js +1 -1
  8. package/components/EnrichedChip.js +2 -2
  9. package/components/EnrichedTypography.js +2 -2
  10. package/components/RetryFailedEnrichments.js +1 -1
  11. package/components/SourcePicker.js +1 -1
  12. package/components/actions/ActionForm.js +1 -1
  13. package/components/actions/ExecutePopover.js +1 -1
  14. package/components/actions/ResultModal.js +2 -3
  15. package/components/actions/formats/FileResult.d.ts +16 -0
  16. package/components/actions/formats/FileResult.js +112 -0
  17. package/components/actions/formats/index.d.ts +8 -0
  18. package/components/actions/formats/index.js +23 -0
  19. package/components/enrichment/EnrichPopover.js +1 -2
  20. package/components/fetchers/Fetcher.js +1 -1
  21. package/components/group/GroupControl.js +1 -2
  22. package/components/stats/QueryStatus.js +1 -1
  23. package/en/translation.json +10 -0
  24. package/fr/translation.json +10 -0
  25. package/hooks/ClueActionContext.d.ts +5 -0
  26. package/hooks/ClueActionContext.js +2 -2
  27. package/hooks/ClueGroupContext.js +1 -1
  28. package/hooks/CluePopupContext.js +2 -2
  29. package/hooks/ClueProvider.js +2 -2
  30. package/hooks/selectors.js +9 -21
  31. package/hooks/useActionResult.js +2 -2
  32. package/hooks/useAnnotations.js +1 -1
  33. package/hooks/useClueActions.js +1 -1
  34. package/hooks/useErrors.js +1 -1
  35. package/icons/Action.js +2 -2
  36. package/icons/Assessment.js +1 -1
  37. package/icons/Context.js +1 -1
  38. package/icons/Opinion.js +1 -1
  39. package/main.js +8 -9
  40. package/package.json +3 -1
  41. package/types/RunningActionData.d.ts +1 -0
@@ -15,8 +15,10 @@ import { u as useContextSelector, c as createContext, a as useContext } from "./
15
15
  import ErrorBoundary from "./components/ErrorBoundary.js";
16
16
  import { adaptSchema } from "./components/actions/form/schemaAdapter.js";
17
17
  import { I as Icon } from "./iconify-CXMreGTg.js";
18
- import Markdown from "./components/display/markdown/index.js";
18
+ import { C as ClueEnrichContext } from "./ClueEnrichContext-DzZhWGxh.js";
19
+ import { ClueFetcherContext } from "./hooks/ClueFetcherContext.js";
19
20
  import ClassificationChip from "./components/ClassificationChip.js";
21
+ import Result from "./components/actions/formats/index.js";
20
22
  import { SNACKBAR_EVENT_ID } from "./data/event.js";
21
23
  import { dayjs } from "./utils/time.js";
22
24
  import { safeDispatchEvent } from "./utils/window.js";
@@ -59,10 +61,22 @@ var upperFirst = createCaseFirst("toUpperCase");
59
61
  function capitalize(string) {
60
62
  return upperFirst(toString(string).toLowerCase());
61
63
  }
64
+ const useClueFetcherSelector = (selector) => {
65
+ return useContextSelector(ClueFetcherContext, selector);
66
+ };
67
+ const useClueActionsSelector = (selector) => {
68
+ return useContextSelector(ClueActionContext, selector);
69
+ };
70
+ const useClueEnrichSelector = (selector) => {
71
+ return useContextSelector(ClueEnrichContext, selector);
72
+ };
73
+ const useClueComponentSelector = (selector) => {
74
+ return useContextSelector(ClueComponentContext, selector);
75
+ };
62
76
  const useActionResult = (resultWithData, interval = 2e3) => {
63
77
  const [result, setResult] = useState(resultWithData);
64
78
  const timeoutRef = useRef(null);
65
- const { getActionStatus } = useClueActions();
79
+ const getActionStatus = useClueActionsSelector((ctx) => ctx.getActionStatus);
66
80
  const taskId = useMemo(() => resultWithData == null ? void 0 : resultWithData.task_id, [resultWithData == null ? void 0 : resultWithData.task_id]);
67
81
  const actionId = useMemo(() => resultWithData == null ? void 0 : resultWithData.actionId, [resultWithData == null ? void 0 : resultWithData.actionId]);
68
82
  useEffect(() => {
@@ -115,10 +129,7 @@ const ResultModal = ({ result: _result, onClose, show = false }) => {
115
129
  ] }),
116
130
  /* @__PURE__ */ jsx(Typography, { variant: "body1", children: result.action.summary }),
117
131
  /* @__PURE__ */ jsx(Divider, { flexItem: true }),
118
- resultFinished ? /* @__PURE__ */ jsx(ErrorBoundary, { children: result.format === "markdown" ? /* @__PURE__ */ jsx(Markdown, { md: result.output }) : result.format === "json" ? /* @__PURE__ */ jsx(JSONViewer, { data: result.output, collapse: true, forceCompact: true }) : /* @__PURE__ */ jsxs(Stack, { sx: { overflowY: "auto" }, children: [
119
- /* @__PURE__ */ jsx(Markdown, { md: "`" + result.format + "` is not recognized as a format in this application." }),
120
- /* @__PURE__ */ jsx(JSONViewer, { data: result, collapse: true, forceCompact: true })
121
- ] }) }) : /* @__PURE__ */ jsxs(Stack, { flex: 1, sx: { pt: 2, alignItems: "center" }, spacing: 1, children: [
132
+ resultFinished ? /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Result, { result }) }) : /* @__PURE__ */ jsxs(Stack, { flex: 1, sx: { pt: 2, alignItems: "center" }, spacing: 1, children: [
122
133
  result.summary && /* @__PURE__ */ jsx(Typography, { variant: "caption", children: result.summary }),
123
134
  /* @__PURE__ */ jsx(
124
135
  LinearProgress,
@@ -184,11 +195,12 @@ const ClueActionProvider = ({
184
195
  );
185
196
  const executeAction = useCallback(
186
197
  async (actionId, selectors, params, options) => {
187
- const { forceMenu, onComplete, skipMenu, skipResultModal, timeout, includeContext, extraContext } = {
198
+ const { forceMenu, onComplete, onCancel, skipMenu, skipResultModal, timeout, includeContext, extraContext } = {
188
199
  forceMenu: false,
189
200
  skipResultModal: false,
190
201
  skipMenu: false,
191
202
  onComplete: null,
203
+ onCancel: null,
192
204
  timeout: null,
193
205
  includeContext: defaultIncludeContext ?? false,
194
206
  extraContext: null,
@@ -242,6 +254,7 @@ const ClueActionProvider = ({
242
254
  skipResultModal,
243
255
  context: context2,
244
256
  onComplete,
257
+ onCancel,
245
258
  timeout
246
259
  });
247
260
  return;
@@ -255,7 +268,7 @@ const ClueActionProvider = ({
255
268
  { timeout },
256
269
  requestConfig
257
270
  );
258
- const actionResultWithData = { ...actionResult, actionId, action: actionToRun };
271
+ const actionResultWithData = { ...actionResult, actionId, action: actionToRun, params: validatedParams };
259
272
  onComplete == null ? void 0 : onComplete(actionResultWithData);
260
273
  setActionResults((_results) => {
261
274
  const keys = selectors.map((value) => getHashKey(value.type, value.value, value.classification));
@@ -345,6 +358,7 @@ const ClueActionProvider = ({
345
358
  [requestConfig]
346
359
  );
347
360
  const cancelAction = useCallback(() => {
361
+ runningActionData == null ? void 0 : runningActionData.onCancel();
348
362
  setRunningActionData(null);
349
363
  setLoading(false);
350
364
  }, []);
@@ -560,8 +574,12 @@ export {
560
574
  ActionForm$1 as A,
561
575
  ClueActionProvider as C,
562
576
  ResultModal$1 as R,
563
- ClueActionContext as a,
564
- useActionResult as b,
565
- capitalize as c,
577
+ useClueActionsSelector as a,
578
+ useClueEnrichSelector as b,
579
+ useClueFetcherSelector as c,
580
+ useClueComponentSelector as d,
581
+ capitalize as e,
582
+ useActionResult as f,
583
+ ClueActionContext as g,
566
584
  useClueActions as u
567
585
  };
@@ -4,7 +4,7 @@ import { useTheme, Stack, Typography, Tooltip, Box, IconButton, CircularProgress
4
4
  import Iconified from "./components/display/icons/Iconified.js";
5
5
  import { SNACKBAR_EVENT_ID } from "./data/event.js";
6
6
  import { ClueComponentContext } from "./hooks/ClueComponentContext.js";
7
- import { useClueEnrichSelector } from "./hooks/selectors.js";
7
+ import { b as useClueEnrichSelector } from "./ActionForm-xoGOCx0G.js";
8
8
  import useAnnotations from "./hooks/useAnnotations.js";
9
9
  import useErrors from "./hooks/useErrors.js";
10
10
  import { ICON_MAP } from "./icons/iconMap.js";
@@ -8,7 +8,7 @@ import { useState, useRef, useCallback, useEffect, useMemo } from "react";
8
8
  import { c as createContext, u as useContextSelector } from "./index-BDVjGvMI.js";
9
9
  import { SHOW_EVENT_ID, HIDE_EVENT_ID } from "./data/event.js";
10
10
  import { safeDispatchEvent, safeAddEventListener } from "./utils/window.js";
11
- import { i as isNull } from "./AnnotationDetails-CbXSCkTF.js";
11
+ import { i as isNull } from "./AnnotationDetails-Dbatv1yI.js";
12
12
  const CluePopupContext = createContext(null);
13
13
  const CluePopupProvider = ({ children }) => {
14
14
  const [popupType, setPopupType] = useState(null);
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Popover } from "@mui/material";
3
3
  import React__default, { useRef, useState, useEffect } from "react";
4
- import { A as AnnotationDetails } from "../AnnotationDetails-CbXSCkTF.js";
4
+ import { A as AnnotationDetails } from "../AnnotationDetails-Dbatv1yI.js";
5
5
  const AnnotationDetailPopover = React__default.memo(({ anchorEl, enrichRequest, open, onClose, ...otherProps }) => {
6
6
  var _a, _b, _c;
7
7
  const actionRef = useRef();
@@ -4,13 +4,13 @@ import "@mui/material";
4
4
  import "./display/icons/Iconified.js";
5
5
  import "../data/event.js";
6
6
  import "../hooks/ClueComponentContext.js";
7
- import "../hooks/selectors.js";
7
+ import "../ActionForm-xoGOCx0G.js";
8
8
  import "../hooks/useAnnotations.js";
9
9
  import "../hooks/useErrors.js";
10
10
  import "../icons/iconMap.js";
11
11
  import "../utils/window.js";
12
12
  import "../groupBy-mXHt-nYT.js";
13
- import { A } from "../AnnotationDetails-CbXSCkTF.js";
13
+ import { A } from "../AnnotationDetails-Dbatv1yI.js";
14
14
  import "../useClueTypeConfig-CHWm5uda.js";
15
15
  import "react";
16
16
  import "../index-BDVjGvMI.js";
@@ -1,7 +1,7 @@
1
1
  import "react/jsx-runtime";
2
2
  import "../iconify-CXMreGTg.js";
3
3
  import "@mui/material";
4
- import { A } from "../AnnotationPreview-D5NX8_su.js";
4
+ import { A } from "../AnnotationPreview-BFPdQYFa.js";
5
5
  import "../hooks/useAnnotations.js";
6
6
  import "../utils-CW9CNV1h.js";
7
7
  import "react";
@@ -2,7 +2,7 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { I as Icon } from "../iconify-CXMreGTg.js";
3
3
  import { useTheme, Card, CardHeader, Stack, CircularProgress, Divider, CardContent, Grid, Chip, Typography, Tooltip, Box } from "@mui/material";
4
4
  import { ClueComponentContext } from "../hooks/ClueComponentContext.js";
5
- import { useClueEnrichSelector } from "../hooks/selectors.js";
5
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
6
6
  import useAnnotations from "../hooks/useAnnotations.js";
7
7
  import useErrors from "../hooks/useErrors.js";
8
8
  import AssessmentIcon from "../icons/Assessment.js";
@@ -3,8 +3,8 @@ import { Chip, Tooltip, Box, Stack, CircularProgress } from "@mui/material";
3
3
  import Iconified from "./display/icons/Iconified.js";
4
4
  import { ClueComponentContext } from "../hooks/ClueComponentContext.js";
5
5
  import { ClueGroupContext } from "../hooks/ClueGroupContext.js";
6
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
7
- import { useClueEnrichSelector } from "../hooks/selectors.js";
6
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
7
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
8
8
  import useAnnotations from "../hooks/useAnnotations.js";
9
9
  import ActionIcon from "../icons/Action.js";
10
10
  import AssessmentIcon from "../icons/Assessment.js";
@@ -3,8 +3,8 @@ import { useTheme, Stack, CircularProgress, Tooltip, IconButton } from "@mui/mat
3
3
  import Iconified from "./display/icons/Iconified.js";
4
4
  import { ClueComponentContext } from "../hooks/ClueComponentContext.js";
5
5
  import { ClueGroupContext } from "../hooks/ClueGroupContext.js";
6
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
7
- import { useClueEnrichSelector } from "../hooks/selectors.js";
6
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
7
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
8
8
  import useAnnotations from "../hooks/useAnnotations.js";
9
9
  import ActionIcon from "../icons/Action.js";
10
10
  import AssessmentIcon from "../icons/Assessment.js";
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Button } from "@mui/material";
3
3
  import { ClueComponentContext } from "../hooks/ClueComponentContext.js";
4
- import { useClueEnrichSelector } from "../hooks/selectors.js";
4
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
5
5
  import { u as useContextSelector } from "../index-BDVjGvMI.js";
6
6
  const RetryFailedEnrichments = () => {
7
7
  const enrichFailedEnrichments = useClueEnrichSelector((ctx) => ctx.enrichFailedEnrichments);
@@ -1,6 +1,6 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { Button, Popover, TextField, Divider, Stack, FormControlLabel, Checkbox } from "@mui/material";
3
- import { useClueComponentSelector, useClueEnrichSelector } from "../hooks/selectors.js";
3
+ import { d as useClueComponentSelector, b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
4
4
  import { memo, useState, useEffect } from "react";
5
5
  const SourcePicker = () => {
6
6
  const { t } = useClueComponentSelector((ctx) => ctx.i18next);
@@ -5,7 +5,7 @@ import "@mui/material";
5
5
  import "../display/icons/Iconified.js";
6
6
  import "../../index-Bmoj6JY8.js";
7
7
  import "../../hooks/ClueComponentContext.js";
8
- import { A } from "../../ActionForm-BenaoSSk.js";
8
+ import { A } from "../../ActionForm-xoGOCx0G.js";
9
9
  import "../../utils-CW9CNV1h.js";
10
10
  import "react";
11
11
  import "../../index-BDVjGvMI.js";
@@ -3,7 +3,7 @@ import { I as Icon } from "../../iconify-CXMreGTg.js";
3
3
  import { useTheme, Tooltip, IconButton, CircularProgress, Button, Popover, Paper, Stack, Typography, Box, Divider } from "@mui/material";
4
4
  import Iconified from "../display/icons/Iconified.js";
5
5
  import { ClueComponentContext } from "../../hooks/ClueComponentContext.js";
6
- import { useClueActionsSelector } from "../../hooks/selectors.js";
6
+ import { a as useClueActionsSelector } from "../../ActionForm-xoGOCx0G.js";
7
7
  import useClueConfig from "../../hooks/useClueConfig.js";
8
8
  import { isAccessible } from "../../utils/classificationParser.js";
9
9
  import { useState, useRef, useMemo, useEffect } from "react";
@@ -1,14 +1,13 @@
1
1
  import "react/jsx-runtime";
2
2
  import "../../iconify-CXMreGTg.js";
3
3
  import "@mui/material";
4
- import "../../index-Bmoj6JY8.js";
5
- import "../display/markdown/index.js";
6
4
  import "../../hooks/ClueComponentContext.js";
7
- import { R } from "../../ActionForm-BenaoSSk.js";
5
+ import { R } from "../../ActionForm-xoGOCx0G.js";
8
6
  import "react";
9
7
  import "../../index-BDVjGvMI.js";
10
8
  import "../ClassificationChip.js";
11
9
  import "../ErrorBoundary.js";
10
+ import "./formats/index.js";
12
11
  export {
13
12
  R as default
14
13
  };
@@ -0,0 +1,16 @@
1
+ import { ActionResult } from "../../../types/action";
2
+ import { WithActionData } from "../../../types/WithActionData";
3
+ import { FC } from 'react';
4
+
5
+ export interface ActionFileResult {
6
+ data: string;
7
+ mime_type: string;
8
+ file_name: string;
9
+ }
10
+ /**
11
+ * Render a file action result with metadata, hash statistics, and download support.
12
+ */
13
+ declare const FileResult: FC<{
14
+ result: WithActionData<ActionResult<ActionFileResult>>;
15
+ }>;
16
+ export default FileResult;
@@ -0,0 +1,112 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Stack, Typography, Divider, Table, TableBody, TableRow, TableCell, Button } from "@mui/material";
3
+ import Iconified from "../../display/icons/Iconified.js";
4
+ import { ClueComponentContext } from "../../../hooks/ClueComponentContext.js";
5
+ import { useState, useMemo, useEffect } from "react";
6
+ import { u as useContextSelector } from "../../../index-BDVjGvMI.js";
7
+ const decodeBase64ToBytes = (base64Data) => {
8
+ const byteCharacters = atob(base64Data);
9
+ const byteArray = new Uint8Array(new ArrayBuffer(byteCharacters.length));
10
+ for (let i = 0; i < byteCharacters.length; i++) {
11
+ byteArray[i] = byteCharacters.charCodeAt(i);
12
+ }
13
+ return byteArray;
14
+ };
15
+ const formatBytes = (bytes) => {
16
+ if (bytes === 0) {
17
+ return "0 B";
18
+ }
19
+ const units = ["B", "KB", "MB", "GB"];
20
+ const unitIndex = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
21
+ const value = bytes / 1024 ** unitIndex;
22
+ return `${value.toFixed(unitIndex === 0 ? 0 : 2)} ${units[unitIndex]}`;
23
+ };
24
+ const saveFileFromServer = (output) => {
25
+ const byteArray = decodeBase64ToBytes(output.data);
26
+ const blob = new Blob([byteArray], { type: output.mime_type || "application/octet-stream" });
27
+ const url = URL.createObjectURL(blob);
28
+ const link = document.createElement("a");
29
+ link.href = url;
30
+ link.download = output.file_name || "result.txt";
31
+ document.body.appendChild(link);
32
+ link.click();
33
+ document.body.removeChild(link);
34
+ URL.revokeObjectURL(url);
35
+ };
36
+ const FileResult = ({ result }) => {
37
+ var _a, _b, _c, _d, _e;
38
+ const { t } = useContextSelector(ClueComponentContext, (ctx) => ctx == null ? void 0 : ctx.i18next);
39
+ const [sha256Hash, setSha256Hash] = useState("");
40
+ const actionName = ((_a = result.action) == null ? void 0 : _a.name) ?? t("actions.result.file.unknown");
41
+ const outputBytes = useMemo(() => {
42
+ var _a2;
43
+ if (!((_a2 = result.output) == null ? void 0 : _a2.data)) {
44
+ return null;
45
+ }
46
+ try {
47
+ return decodeBase64ToBytes(result.output.data);
48
+ } catch {
49
+ return null;
50
+ }
51
+ }, [(_b = result.output) == null ? void 0 : _b.data]);
52
+ useEffect(() => {
53
+ let cancelled = false;
54
+ const generateHash = async () => {
55
+ if (!outputBytes || typeof crypto === "undefined" || !crypto.subtle) {
56
+ setSha256Hash("N/A");
57
+ return;
58
+ }
59
+ const digest = await crypto.subtle.digest("SHA-256", outputBytes);
60
+ const digestArray = Array.from(new Uint8Array(digest));
61
+ const digestHex = digestArray.map((value) => value.toString(16).padStart(2, "0")).join("");
62
+ if (!cancelled) {
63
+ setSha256Hash(digestHex);
64
+ }
65
+ };
66
+ setSha256Hash("");
67
+ generateHash();
68
+ return () => {
69
+ cancelled = true;
70
+ };
71
+ }, [outputBytes]);
72
+ return /* @__PURE__ */ jsxs(Stack, { sx: { overflowY: "auto" }, spacing: 3, children: [
73
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: t("actions.result.file.title", { actionName }) }),
74
+ /* @__PURE__ */ jsx(Typography, { children: t("actions.result.file.description", { actionName }) }),
75
+ /* @__PURE__ */ jsx(Divider, { flexItem: true }),
76
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", children: t("actions.result.file.stats.title") }),
77
+ outputBytes && /* @__PURE__ */ jsx(Table, { sx: { maxWidth: 900 }, children: /* @__PURE__ */ jsxs(TableBody, { children: [
78
+ /* @__PURE__ */ jsxs(TableRow, { children: [
79
+ /* @__PURE__ */ jsx(TableCell, { sx: { width: "35%" }, children: t("actions.result.file.stats.label.decoded_size") }),
80
+ /* @__PURE__ */ jsx(TableCell, { children: formatBytes(outputBytes.length) || "n/a" })
81
+ ] }),
82
+ /* @__PURE__ */ jsxs(TableRow, { children: [
83
+ /* @__PURE__ */ jsx(TableCell, { sx: { width: "35%" }, children: t("actions.result.file.stats.label.decoded_bytes") }),
84
+ /* @__PURE__ */ jsx(TableCell, { children: outputBytes.length || "n/a" })
85
+ ] }),
86
+ /* @__PURE__ */ jsxs(TableRow, { children: [
87
+ /* @__PURE__ */ jsx(TableCell, { sx: { width: "35%" }, children: t("actions.result.file.stats.label.base64_length") }),
88
+ /* @__PURE__ */ jsx(TableCell, { children: ((_c = result.output) == null ? void 0 : _c.data.length) ?? "n/a" })
89
+ ] }),
90
+ /* @__PURE__ */ jsxs(TableRow, { children: [
91
+ /* @__PURE__ */ jsx(TableCell, { sx: { width: "35%" }, children: t("actions.result.file.stats.label.sha256") }),
92
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx("code", { children: sha256Hash || t("actions.result.file.stats.calculating") }) })
93
+ ] })
94
+ ] }) }),
95
+ /* @__PURE__ */ jsx(
96
+ Button,
97
+ {
98
+ startIcon: /* @__PURE__ */ jsx(Iconified, { icon: "ic:baseline-download" }),
99
+ variant: "outlined",
100
+ sx: { alignSelf: "center" },
101
+ disabled: !((_d = result.output) == null ? void 0 : _d.data),
102
+ onClick: () => result.output && saveFileFromServer(result.output),
103
+ name: "download",
104
+ role: "button",
105
+ children: t("download", { file: ((_e = result.output) == null ? void 0 : _e.file_name) ?? "result.txt" })
106
+ }
107
+ )
108
+ ] });
109
+ };
110
+ export {
111
+ FileResult as default
112
+ };
@@ -0,0 +1,8 @@
1
+ import { ActionResult } from "../../../types/action";
2
+ import { WithActionData } from "../../../types/WithActionData";
3
+ import { FC } from 'react';
4
+
5
+ declare const Result: FC<{
6
+ result: WithActionData<ActionResult>;
7
+ }>;
8
+ export default Result;
@@ -0,0 +1,23 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Stack } from "@mui/material";
3
+ import { J as JSONViewer } from "../../../index-Bmoj6JY8.js";
4
+ import Markdown from "../../display/markdown/index.js";
5
+ import FileResult from "./FileResult.js";
6
+ const Result = ({ result }) => {
7
+ if (result.format === "markdown") {
8
+ return /* @__PURE__ */ jsx(Markdown, { md: result.output });
9
+ }
10
+ if (result.format === "json") {
11
+ return /* @__PURE__ */ jsx(JSONViewer, { data: result.output, collapse: true, forceCompact: true });
12
+ }
13
+ if (result.format === "file") {
14
+ return /* @__PURE__ */ jsx(FileResult, { result });
15
+ }
16
+ return /* @__PURE__ */ jsxs(Stack, { sx: { overflowY: "auto" }, children: [
17
+ /* @__PURE__ */ jsx(Markdown, { md: "`" + result.format + "` is not recognized as a format in this application." }),
18
+ /* @__PURE__ */ jsx(JSONViewer, { data: result, collapse: true, forceCompact: true })
19
+ ] });
20
+ };
21
+ export {
22
+ Result as default
23
+ };
@@ -1,7 +1,6 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { useTheme, Tooltip, IconButton, CircularProgress, Button, Popover, Paper, Stack, Box, Typography, Divider } from "@mui/material";
3
- import { useClueComponentSelector, useClueEnrichSelector } from "../../hooks/selectors.js";
4
- import { c as capitalize } from "../../ActionForm-BenaoSSk.js";
3
+ import { d as useClueComponentSelector, b as useClueEnrichSelector, e as capitalize } from "../../ActionForm-xoGOCx0G.js";
5
4
  import { useState, useRef, useCallback, useEffect } from "react";
6
5
  import Iconified from "../display/icons/Iconified.js";
7
6
  const EnrichPopover = ({ show = false, size = "small", selector }) => {
@@ -5,7 +5,7 @@ import { F as FlexOne } from "../../FlexOne-BSYAhhtG.js";
5
5
  import Iconified from "../display/icons/Iconified.js";
6
6
  import { J as JSONViewer } from "../../index-Bmoj6JY8.js";
7
7
  import { ClueComponentContext } from "../../hooks/ClueComponentContext.js";
8
- import { useClueFetcherSelector } from "../../hooks/selectors.js";
8
+ import { c as useClueFetcherSelector } from "../../ActionForm-xoGOCx0G.js";
9
9
  import React__default, { useState, useEffect, memo } from "react";
10
10
  import { u as useContextSelector } from "../../index-BDVjGvMI.js";
11
11
  import Graph from "../display/graph/index.js";
@@ -4,9 +4,8 @@ import { F as FlexOne } from "../../FlexOne-BSYAhhtG.js";
4
4
  import Iconified from "../display/icons/Iconified.js";
5
5
  import { SNACKBAR_EVENT_ID } from "../../data/event.js";
6
6
  import { ClueGroupContext } from "../../hooks/ClueGroupContext.js";
7
- import { useClueComponentSelector, useClueEnrichSelector } from "../../hooks/selectors.js";
7
+ import { d as useClueComponentSelector, b as useClueEnrichSelector, e as capitalize } from "../../ActionForm-xoGOCx0G.js";
8
8
  import { safeDispatchEvent } from "../../utils/window.js";
9
- import { c as capitalize } from "../../ActionForm-BenaoSSk.js";
10
9
  import { useState, useMemo, useCallback } from "react";
11
10
  import { u as useContextSelector } from "../../index-BDVjGvMI.js";
12
11
  import ExecutePopover from "../actions/ExecutePopover.js";
@@ -1,7 +1,7 @@
1
1
  import { jsxs } from "react/jsx-runtime";
2
2
  import { Stack, Typography } from "@mui/material";
3
3
  import { ClueDatabaseContext } from "../../hooks/ClueDatabaseContext.js";
4
- import { useClueComponentSelector, useClueEnrichSelector } from "../../hooks/selectors.js";
4
+ import { d as useClueComponentSelector, b as useClueEnrichSelector } from "../../ActionForm-xoGOCx0G.js";
5
5
  import { useContext, useState, useEffect } from "react";
6
6
  const QueryStatus = () => {
7
7
  const { t } = useClueComponentSelector((ctx) => ctx.i18next);
@@ -6,6 +6,15 @@
6
6
  "actions.executing": "Executing",
7
7
  "actions.json.hide": "Hide JSON",
8
8
  "actions.json.show": "Show JSON",
9
+ "actions.result.file.description": "The action {{actionName}} has provided a file for download. If you wish to download the result, use the download button below.",
10
+ "actions.result.file.stats.calculating": "Calculating...",
11
+ "actions.result.file.stats.label.base64_length": "Base64 Length:",
12
+ "actions.result.file.stats.label.decoded_bytes": "Decoded Bytes:",
13
+ "actions.result.file.stats.label.decoded_size": "Decoded Size:",
14
+ "actions.result.file.stats.label.sha256": "SHA-256:",
15
+ "actions.result.file.stats.title": "File statistics",
16
+ "actions.result.file.title": "{{actionName}} has provided a file",
17
+ "actions.result.file.unknown": "Unknown",
9
18
  "adminmenu": "Admin menu",
10
19
  "adminmenu.config": "Configuration",
11
20
  "adminmenu.users": "Users",
@@ -24,6 +33,7 @@
24
33
  "clipboard.success": "was copied to clipboard.",
25
34
  "close": "Close",
26
35
  "details.open": "Open Details",
36
+ "download": "Download {{file}}",
27
37
  "drawer.chat": "Chat",
28
38
  "drawer.collapse": "Collapse Menu",
29
39
  "drawer.dashboard": "Dashboard",
@@ -6,6 +6,15 @@
6
6
  "actions.executing": "Executing",
7
7
  "actions.json.hide": "Masquer JSON",
8
8
  "actions.json.show": "Afficher JSON",
9
+ "actions.result.file.description": "L'action {{actionName}} a fourni un fichier à télécharger. Si vous souhaitez télécharger le résultat, utilisez le bouton de téléchargement ci-dessous.",
10
+ "actions.result.file.stats.calculating": "Calcul en cours...",
11
+ "actions.result.file.stats.label.base64_length": "Longueur base64 :",
12
+ "actions.result.file.stats.label.decoded_bytes": "Octets décodés :",
13
+ "actions.result.file.stats.label.decoded_size": "Taille décodée :",
14
+ "actions.result.file.stats.label.sha256": "SHA-256 :",
15
+ "actions.result.file.stats.title": "Statistiques du fichier",
16
+ "actions.result.file.title": "{{actionName}} a fourni un fichier",
17
+ "actions.result.file.unknown": "Inconnu",
9
18
  "adminmenu": "Menu d'administration",
10
19
  "adminmenu.config": "Configuration",
11
20
  "adminmenu.users": "Usagers",
@@ -24,6 +33,7 @@
24
33
  "clipboard.success": "a été copié dans le presse-papiers.",
25
34
  "close": "Fermer",
26
35
  "details.open": "Ouvrir les détails",
36
+ "download": "Télécharger {{file}}",
27
37
  "drawer.chat": "Clavardage",
28
38
  "drawer.collapse": "Fermer le Menu",
29
39
  "drawer.dashboard": "Tableau de bord",
@@ -43,6 +43,11 @@ export interface ClueActionContextType {
43
43
  * @returns The action result
44
44
  */
45
45
  onComplete?: (result: WithActionData<ActionResult>) => void;
46
+ /**
47
+ * Callback for when the action is cancelled
48
+ * @returns void
49
+ */
50
+ onCancel?: () => void;
46
51
  /**
47
52
  * how long should the action have to respond?
48
53
  */
@@ -2,7 +2,7 @@ import "react/jsx-runtime";
2
2
  import "@mui/material";
3
3
  import "../index-CC12Ux-9.js";
4
4
  import "../useClueTypeConfig-CHWm5uda.js";
5
- import { a, C } from "../ActionForm-BenaoSSk.js";
5
+ import { g, C } from "../ActionForm-xoGOCx0G.js";
6
6
  import "../components/display/icons/Iconified.js";
7
7
  import "../components/ErrorBoundary.js";
8
8
  import "../data/event.js";
@@ -14,6 +14,6 @@ import "./ClueComponentContext.js";
14
14
  import "./useClue.js";
15
15
  import "../isNil-CIubwp4T.js";
16
16
  export {
17
- a as ClueActionContext,
17
+ g as ClueActionContext,
18
18
  C as ClueActionProvider
19
19
  };
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useState, useMemo } from "react";
3
3
  import { c as createContext } from "../index-BDVjGvMI.js";
4
- import { useClueEnrichSelector } from "./selectors.js";
4
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
5
5
  const ClueGroupContext = createContext(null);
6
6
  const ClueGroupProvider = ({ children, type, classification }) => {
7
7
  const defaultClassification = useClueEnrichSelector((ctx) => ctx.defaultClassification);
@@ -1,9 +1,9 @@
1
1
  import "react/jsx-runtime";
2
2
  import "../components/AnnotationDetailPopover.js";
3
- import { C, a } from "../AnnotationPreview-D5NX8_su.js";
3
+ import { C, a } from "../AnnotationPreview-BFPdQYFa.js";
4
4
  import "../data/event.js";
5
5
  import "../utils/window.js";
6
- import "../AnnotationDetails-CbXSCkTF.js";
6
+ import "../AnnotationDetails-Dbatv1yI.js";
7
7
  import "react";
8
8
  import "../index-BDVjGvMI.js";
9
9
  export {
@@ -1,11 +1,11 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { C as ClueActionProvider } from "../ActionForm-BenaoSSk.js";
2
+ import { C as ClueActionProvider } from "../ActionForm-xoGOCx0G.js";
3
3
  import { ClueComponentProvider } from "./ClueComponentContext.js";
4
4
  import { ClueConfigProvider } from "./ClueConfigProvider.js";
5
5
  import { ClueDatabaseProvider } from "./ClueDatabaseContext.js";
6
6
  import { a as ClueEnrichProvider } from "../ClueEnrichContext-DzZhWGxh.js";
7
7
  import { ClueFetcherProvider } from "./ClueFetcherContext.js";
8
- import { a as CluePopupProvider } from "../AnnotationPreview-D5NX8_su.js";
8
+ import { a as CluePopupProvider } from "../AnnotationPreview-BFPdQYFa.js";
9
9
  const ClueProvider = ({ children, ...props }) => {
10
10
  return /* @__PURE__ */ jsx(ClueComponentProvider, { ...props, children: /* @__PURE__ */ jsx(ClueConfigProvider, { config: props.config, children: /* @__PURE__ */ jsx(ClueDatabaseProvider, { ...props, children: /* @__PURE__ */ jsx(ClueEnrichProvider, { ...props, children: /* @__PURE__ */ jsx(ClueFetcherProvider, { ...props, children: /* @__PURE__ */ jsx(ClueActionProvider, { ...props, children: /* @__PURE__ */ jsx(CluePopupProvider, { children }) }) }) }) }) }) });
11
11
  };
@@ -1,23 +1,11 @@
1
- import { a as ClueActionContext } from "../ActionForm-BenaoSSk.js";
2
- import { ClueComponentContext } from "./ClueComponentContext.js";
3
- import { C as ClueEnrichContext } from "../ClueEnrichContext-DzZhWGxh.js";
4
- import { ClueFetcherContext } from "./ClueFetcherContext.js";
5
- import { u as useContextSelector } from "../index-BDVjGvMI.js";
6
- const useClueFetcherSelector = (selector) => {
7
- return useContextSelector(ClueFetcherContext, selector);
8
- };
9
- const useClueActionsSelector = (selector) => {
10
- return useContextSelector(ClueActionContext, selector);
11
- };
12
- const useClueEnrichSelector = (selector) => {
13
- return useContextSelector(ClueEnrichContext, selector);
14
- };
15
- const useClueComponentSelector = (selector) => {
16
- return useContextSelector(ClueComponentContext, selector);
17
- };
1
+ import { a, d, b, c } from "../ActionForm-xoGOCx0G.js";
2
+ import "./ClueComponentContext.js";
3
+ import "../ClueEnrichContext-DzZhWGxh.js";
4
+ import "./ClueFetcherContext.js";
5
+ import "../index-BDVjGvMI.js";
18
6
  export {
19
- useClueActionsSelector,
20
- useClueComponentSelector,
21
- useClueEnrichSelector,
22
- useClueFetcherSelector
7
+ a as useClueActionsSelector,
8
+ d as useClueComponentSelector,
9
+ b as useClueEnrichSelector,
10
+ c as useClueFetcherSelector
23
11
  };
@@ -1,5 +1,5 @@
1
1
  import "react";
2
- import { b } from "../ActionForm-BenaoSSk.js";
2
+ import { f } from "../ActionForm-xoGOCx0G.js";
3
3
  export {
4
- b as useActionResult
4
+ f as useActionResult
5
5
  };
@@ -1,7 +1,7 @@
1
1
  import { u as uniqBy } from "../ClueEnrichContext-DzZhWGxh.js";
2
2
  import { useContext, useMemo, useState, useEffect } from "react";
3
3
  import { ClueDatabaseContext } from "./ClueDatabaseContext.js";
4
- import { useClueEnrichSelector } from "./selectors.js";
4
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
5
5
  const useAnnotations = (type, value, _classification, { skipEnrichment } = { skipEnrichment: false }) => {
6
6
  const database = useContext(ClueDatabaseContext);
7
7
  const defaultClassification = useClueEnrichSelector((ctx) => ctx.defaultClassification);
@@ -1,4 +1,4 @@
1
- import { u } from "../ActionForm-BenaoSSk.js";
1
+ import { u } from "../ActionForm-xoGOCx0G.js";
2
2
  import "../index-BDVjGvMI.js";
3
3
  export {
4
4
  u as default
@@ -1,6 +1,6 @@
1
1
  import { useContext, useState, useEffect } from "react";
2
2
  import { ClueDatabaseContext } from "./ClueDatabaseContext.js";
3
- import { useClueEnrichSelector } from "./selectors.js";
3
+ import { b as useClueEnrichSelector } from "../ActionForm-xoGOCx0G.js";
4
4
  const useErrors = (value) => {
5
5
  const database = useContext(ClueDatabaseContext);
6
6
  const ready = useClueEnrichSelector((ctx) => ctx.ready);
package/icons/Action.js CHANGED
@@ -2,8 +2,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { I as Icon } from "../iconify-CXMreGTg.js";
3
3
  import { useTheme, Stack, Divider, Typography } from "@mui/material";
4
4
  import CountBadge from "../components/CountBadge.js";
5
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
6
- import { u as useClueActions } from "../ActionForm-BenaoSSk.js";
5
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
6
+ import { u as useClueActions } from "../ActionForm-xoGOCx0G.js";
7
7
  import { g as groupBy } from "../groupBy-mXHt-nYT.js";
8
8
  import { memo, useRef, useMemo, useEffect } from "react";
9
9
  import { u as useContextSelector } from "../index-BDVjGvMI.js";
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { I as Icon } from "../iconify-CXMreGTg.js";
3
3
  import { useTheme, Stack, Chip, Divider, Grid, Tooltip } from "@mui/material";
4
4
  import CountBadge from "../components/CountBadge.js";
5
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
5
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
6
6
  import { g as groupBy } from "../groupBy-mXHt-nYT.js";
7
7
  import { l as last } from "../last-CUCl67Im.js";
8
8
  import { m as maxBy, s as sortBy } from "../sortBy-B0zptFuY.js";
package/icons/Context.js CHANGED
@@ -4,7 +4,7 @@ import { Stack, Divider } from "@mui/material";
4
4
  import AnnotationEntry from "../components/AnnotationEntry.js";
5
5
  import CountBadge from "../components/CountBadge.js";
6
6
  import Iconified from "../components/display/icons/Iconified.js";
7
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
7
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
8
8
  import { g as groupBy } from "../groupBy-mXHt-nYT.js";
9
9
  import { memo, useRef, useMemo, useEffect } from "react";
10
10
  import { u as useContextSelector } from "../index-BDVjGvMI.js";
package/icons/Opinion.js CHANGED
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { I as Icon } from "../iconify-CXMreGTg.js";
3
3
  import { useTheme, Stack, Chip, Divider, Grid } from "@mui/material";
4
4
  import CountBadge from "../components/CountBadge.js";
5
- import { C as CluePopupContext } from "../AnnotationPreview-D5NX8_su.js";
5
+ import { C as CluePopupContext } from "../AnnotationPreview-BFPdQYFa.js";
6
6
  import chain from "../utils/chain.js";
7
7
  import { g as groupBy } from "../groupBy-mXHt-nYT.js";
8
8
  import { s as sortBy } from "../sortBy-B0zptFuY.js";
package/main.js CHANGED
@@ -1,8 +1,8 @@
1
- import { A, u } from "./ActionForm-BenaoSSk.js";
1
+ import { A, u, a, b, c } from "./ActionForm-xoGOCx0G.js";
2
2
  import { default as default2 } from "./components/AnnotationDetailPopover.js";
3
- import { A as A2 } from "./AnnotationDetails-CbXSCkTF.js";
3
+ import { A as A2 } from "./AnnotationDetails-Dbatv1yI.js";
4
4
  import { default as default3 } from "./components/AnnotationEntry.js";
5
- import { A as A3, C } from "./AnnotationPreview-D5NX8_su.js";
5
+ import { A as A3, C } from "./AnnotationPreview-BFPdQYFa.js";
6
6
  import { default as default4 } from "./components/CountBadge.js";
7
7
  import { default as default5 } from "./components/EnrichedCard.js";
8
8
  import { default as default6 } from "./components/EnrichedChip.js";
@@ -14,13 +14,12 @@ import { default as default11 } from "./components/group/Group.js";
14
14
  import { default as default12 } from "./components/group/GroupControl.js";
15
15
  import { default as default13 } from "./components/SourcePicker.js";
16
16
  import { SNACKBAR_EVENT_ID } from "./data/event.js";
17
- import { b } from "./index-CC12Ux-9.js";
17
+ import { b as b2 } from "./index-CC12Ux-9.js";
18
18
  import { ClueComponentContext } from "./hooks/ClueComponentContext.js";
19
19
  import { ClueConfigContext } from "./hooks/ClueConfigProvider.js";
20
20
  import { ClueDatabaseContext } from "./hooks/ClueDatabaseContext.js";
21
21
  import { C as C2 } from "./ClueEnrichContext-DzZhWGxh.js";
22
22
  import { ClueProvider } from "./hooks/ClueProvider.js";
23
- import { useClueActionsSelector, useClueEnrichSelector, useClueFetcherSelector } from "./hooks/selectors.js";
24
23
  import { default as default14 } from "./hooks/useClue.js";
25
24
  import { default as default15 } from "./hooks/useClueConfig.js";
26
25
  import { default as default16 } from "./icons/Assessment.js";
@@ -54,11 +53,11 @@ export {
54
53
  SNACKBAR_EVENT_ID,
55
54
  default13 as SourcePicker,
56
55
  default9 as StatusChip,
57
- b as buildDatabase,
56
+ b2 as buildDatabase,
58
57
  default14 as useClue,
59
58
  u as useClueActions,
60
- useClueActionsSelector,
59
+ a as useClueActionsSelector,
61
60
  default15 as useClueConfig,
62
- useClueEnrichSelector,
63
- useClueFetcherSelector
61
+ b as useClueEnrichSelector,
62
+ c as useClueFetcherSelector
64
63
  };
package/package.json CHANGED
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "type": "module",
68
68
  "types": "main.d.ts",
69
- "version": "1.2.0-dev.177",
69
+ "version": "1.2.0-dev.182",
70
70
  "exports": {
71
71
  ".": "./main.js",
72
72
  "./index.css": "./index.css",
@@ -104,6 +104,8 @@
104
104
  "./components/display/graph/visualizations/tree/*": "./components/display/graph/visualizations/tree/*.js",
105
105
  "./components/display/graph/visualizations/tree": "./components/display/graph/visualizations/tree/index.js",
106
106
  "./components/display/graph/visualizations/panels/*": "./components/display/graph/visualizations/panels/*.js",
107
+ "./components/actions/formats/*": "./components/actions/formats/*.js",
108
+ "./components/actions/formats": "./components/actions/formats/index.js",
107
109
  "./components/actions/form/*": "./components/actions/form/*.js"
108
110
  }
109
111
  }
@@ -11,6 +11,7 @@ interface RunningActionData {
11
11
  context?: ActionContextInformation;
12
12
  skipResultModal?: boolean;
13
13
  onComplete?: (result: WithActionData<ActionResult>) => void;
14
+ onCancel?: () => void;
14
15
  timeout?: number;
15
16
  }
16
17