synapse-react-client 4.0.27 → 4.0.29

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 (86) hide show
  1. package/dist/SWC.index.js +1 -1
  2. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  3. package/dist/components/DataGrid/SynapseGrid.js +102 -94
  4. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  5. package/dist/components/DataGrid/components/GridMenuButton/GridMenuButton.d.ts +4 -1
  6. package/dist/components/DataGrid/components/GridMenuButton/GridMenuButton.d.ts.map +1 -1
  7. package/dist/components/DataGrid/components/GridMenuButton/GridMenuButton.js +1 -0
  8. package/dist/components/DataGrid/components/GridMenuButton/GridMenuButton.js.map +1 -1
  9. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
  10. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +12 -3
  11. package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
  12. package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -1
  13. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +13 -10
  14. package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -1
  15. package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +20 -0
  16. package/dist/features/curator/dashboard/components/CurationTaskCardLayout.d.ts.map +1 -1
  17. package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js +62 -49
  18. package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js.map +1 -1
  19. package/dist/features/entity/metadata-task/components/MetadataTasksPage.d.ts.map +1 -1
  20. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +33 -34
  21. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js.map +1 -1
  22. package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.d.ts.map +1 -1
  23. package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.js +16 -20
  24. package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.js.map +1 -1
  25. package/dist/features/entity/metadata-task/create-task/ComputeTaskForm.d.ts +1 -1
  26. package/dist/features/entity/metadata-task/create-task/ComputeTaskForm.d.ts.map +1 -1
  27. package/dist/features/entity/metadata-task/create-task/ComputeTaskForm.js +89 -122
  28. package/dist/features/entity/metadata-task/create-task/ComputeTaskForm.js.map +1 -1
  29. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.d.ts +1 -1
  30. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.d.ts.map +1 -1
  31. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js +77 -102
  32. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js.map +1 -1
  33. package/dist/features/entity/metadata-task/create-task/FileBasedFields.d.ts +6 -1
  34. package/dist/features/entity/metadata-task/create-task/FileBasedFields.d.ts.map +1 -1
  35. package/dist/features/entity/metadata-task/create-task/FileBasedFields.js +9 -2
  36. package/dist/features/entity/metadata-task/create-task/FileBasedFields.js.map +1 -1
  37. package/dist/features/entity/metadata-task/create-task/RecordBasedFields.d.ts +5 -1
  38. package/dist/features/entity/metadata-task/create-task/RecordBasedFields.d.ts.map +1 -1
  39. package/dist/features/entity/metadata-task/create-task/RecordBasedFields.js +6 -2
  40. package/dist/features/entity/metadata-task/create-task/RecordBasedFields.js.map +1 -1
  41. package/dist/features/entity/metadata-task/create-task/RecordSetFields.d.ts +7 -1
  42. package/dist/features/entity/metadata-task/create-task/RecordSetFields.d.ts.map +1 -1
  43. package/dist/features/entity/metadata-task/create-task/RecordSetFields.js +10 -2
  44. package/dist/features/entity/metadata-task/create-task/RecordSetFields.js.map +1 -1
  45. package/dist/features/entity/metadata-task/create-task/SampleSheetFields.d.ts +6 -1
  46. package/dist/features/entity/metadata-task/create-task/SampleSheetFields.d.ts.map +1 -1
  47. package/dist/features/entity/metadata-task/create-task/SampleSheetFields.js +9 -2
  48. package/dist/features/entity/metadata-task/create-task/SampleSheetFields.js.map +1 -1
  49. package/dist/features/entity/metadata-task/create-task/TaskStatusField.d.ts +19 -0
  50. package/dist/features/entity/metadata-task/create-task/TaskStatusField.d.ts.map +1 -0
  51. package/dist/features/entity/metadata-task/create-task/TaskStatusField.js +32 -0
  52. package/dist/features/entity/metadata-task/create-task/TaskStatusField.js.map +1 -0
  53. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.d.ts +21 -0
  54. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.d.ts.map +1 -0
  55. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js +100 -0
  56. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js.map +1 -0
  57. package/dist/features/entity/metadata-task/create-task/useComputeTypeFields.d.ts +24 -0
  58. package/dist/features/entity/metadata-task/create-task/useComputeTypeFields.d.ts.map +1 -0
  59. package/dist/features/entity/metadata-task/create-task/useComputeTypeFields.js +56 -0
  60. package/dist/features/entity/metadata-task/create-task/useComputeTypeFields.js.map +1 -0
  61. package/dist/features/entity/metadata-task/create-task/useCurateTypeFields.d.ts +26 -0
  62. package/dist/features/entity/metadata-task/create-task/useCurateTypeFields.d.ts.map +1 -0
  63. package/dist/features/entity/metadata-task/create-task/useCurateTypeFields.js +57 -0
  64. package/dist/features/entity/metadata-task/create-task/useCurateTypeFields.js.map +1 -0
  65. package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.d.ts +4 -2
  66. package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.d.ts.map +1 -1
  67. package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.js +12 -11
  68. package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.js.map +1 -1
  69. package/dist/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.d.ts +9 -14
  70. package/dist/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.d.ts.map +1 -1
  71. package/dist/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.js +11 -7
  72. package/dist/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.js.map +1 -1
  73. package/dist/features/entity/metadata-task/create-task/utils/buildCurateTaskPayload.d.ts +11 -12
  74. package/dist/features/entity/metadata-task/create-task/utils/buildCurateTaskPayload.d.ts.map +1 -1
  75. package/dist/features/entity/metadata-task/create-task/utils/buildCurateTaskPayload.js +17 -12
  76. package/dist/features/entity/metadata-task/create-task/utils/buildCurateTaskPayload.js.map +1 -1
  77. package/dist/features/entity/metadata-task/utils/constants.d.ts +14 -1
  78. package/dist/features/entity/metadata-task/utils/constants.d.ts.map +1 -1
  79. package/dist/features/entity/metadata-task/utils/constants.js +23 -20
  80. package/dist/features/entity/metadata-task/utils/constants.js.map +1 -1
  81. package/dist/tsconfig.build.tsbuildinfo +1 -1
  82. package/package.json +4 -4
  83. package/dist/features/entity/metadata-task/create-task/CreateCurationTaskFlow.d.ts +0 -18
  84. package/dist/features/entity/metadata-task/create-task/CreateCurationTaskFlow.d.ts.map +0 -1
  85. package/dist/features/entity/metadata-task/create-task/CreateCurationTaskFlow.js +0 -78
  86. package/dist/features/entity/metadata-task/create-task/CreateCurationTaskFlow.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskStatusField.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/TaskStatusField.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAGtE,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAAA;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC9C,QAAQ,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,cAAc,EAAE,mBAAmB,EAAE,CAAA;IACrC,sGAAsG;IACtG,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CAyBlE"}
@@ -0,0 +1,32 @@
1
+ import { StyledFormControl as e } from "../../../../components/styled/StyledFormControl.js";
2
+ import "../../../../components/styled/index.js";
3
+ import { TASK_STATUS_CONFIG as t, TASK_STATUS_INPUT_LABEL as n } from "../utils/constants.js";
4
+ import { InputLabel as r, MenuItem as i, Select as a } from "@mui/material";
5
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
6
+ import { TaskStatusStateEnum as c } from "@sage-bionetworks/synapse-client";
7
+ //#region src/features/entity/metadata-task/create-task/TaskStatusField.tsx
8
+ function l(l) {
9
+ let { value: u, onChange: d, disabled: f, disabledStates: p, labelId: m } = l;
10
+ return /* @__PURE__ */ s(e, {
11
+ fullWidth: !0,
12
+ children: [/* @__PURE__ */ o(r, {
13
+ id: m,
14
+ children: n
15
+ }), /* @__PURE__ */ o(a, {
16
+ labelId: m,
17
+ value: u ?? "",
18
+ label: n,
19
+ disabled: f,
20
+ onChange: (e) => d(e.target.value),
21
+ children: Object.values(c).map((e) => /* @__PURE__ */ o(i, {
22
+ value: e,
23
+ disabled: p.includes(e),
24
+ children: t[e].label
25
+ }, e))
26
+ })]
27
+ });
28
+ }
29
+ //#endregion
30
+ export { l as default };
31
+
32
+ //# sourceMappingURL=TaskStatusField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskStatusField.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/TaskStatusField.tsx"],"sourcesContent":["import { StyledFormControl } from '@/components/styled'\nimport { InputLabel, MenuItem, Select } from '@mui/material'\nimport { TaskStatusStateEnum } from '@sage-bionetworks/synapse-client'\nimport { TASK_STATUS_CONFIG, TASK_STATUS_INPUT_LABEL } from '../utils/constants'\n\nexport type TaskStatusFieldProps = {\n value: TaskStatusStateEnum | undefined\n onChange: (state: TaskStatusStateEnum) => void\n disabled: boolean\n /**\n * States the user must not be able to manually select into (e.g. EXECUTING, which a compute task\n * enters automatically). These still render as `MenuItem`s -- so a task already in one of these\n * states continues to display it correctly -- but are disabled.\n */\n disabledStates: TaskStatusStateEnum[]\n /** Must be unique per rendered instance; passed through to both the `InputLabel` and the `Select`. */\n labelId: string\n}\n\n/**\n * The task status `<Select>` shown in edit mode by both `ComputeTaskForm` and `CurateTaskForm`.\n */\nexport default function TaskStatusField(props: TaskStatusFieldProps) {\n const { value, onChange, disabled, disabledStates, labelId } = props\n\n return (\n <StyledFormControl fullWidth>\n <InputLabel id={labelId}>{TASK_STATUS_INPUT_LABEL}</InputLabel>\n <Select\n labelId={labelId}\n value={value ?? ''}\n label={TASK_STATUS_INPUT_LABEL}\n disabled={disabled}\n onChange={e => onChange(e.target.value as TaskStatusStateEnum)}\n >\n {Object.values(TaskStatusStateEnum).map(state => (\n <MenuItem\n key={state}\n value={state}\n disabled={disabledStates.includes(state)}\n >\n {TASK_STATUS_CONFIG[state].label}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )\n}\n"],"mappings":";;;;;;;AAsBA,SAAwB,EAAgB,GAA6B;CACnE,IAAM,EAAE,UAAO,aAAU,aAAU,mBAAgB,eAAY;CAE/D,OACE,kBAAC,GAAD;EAAmB,WAAA;YAAnB,CACE,kBAAC,GAAD;GAAY,IAAI;aAAU;EAAoC,CAAA,GAC9D,kBAAC,GAAD;GACW;GACT,OAAO,KAAS;GAChB,OAAO;GACG;GACV,WAAU,MAAK,EAAS,EAAE,OAAO,KAA4B;aAE5D,OAAO,OAAO,CAAmB,EAAE,KAAI,MACtC,kBAAC,GAAD;IAEE,OAAO;IACP,UAAU,EAAe,SAAS,CAAK;cAEtC,EAAmB,GAAO;GACnB,GALH,CAKG,CACX;EACK,CAAA,CACS;;AAEvB"}
@@ -0,0 +1,21 @@
1
+ import { RouteObject } from 'react-router';
2
+ export type GetCurationTaskFlowRoutesOptions = {
3
+ /**
4
+ * Present when the host page already has a project context (e.g. a project's Metadata Tasks page).
5
+ * Absent when creating from a context without one (e.g. the Curator Dashboard).
6
+ */
7
+ projectId?: string;
8
+ /**
9
+ * Path (relative to the host router) to navigate to when the user exits the flow -- via "Back to
10
+ * All Tasks" on the category picker/compute/curate forms, or "Back to All Tasks" on the
11
+ * confirmation screen. Typically the host's own index route (`'/'`).
12
+ */
13
+ exitPath: string;
14
+ };
15
+ /**
16
+ * Builds the route objects for the 3-step "Create New Task" wizard: category picker -> compute/curate
17
+ * form -> confirmation. The task itself is created on the step-2-to-step-3 transition (see
18
+ * `ComputeTaskForm`/`CurateTaskForm`'s `onCreated`).
19
+ */
20
+ export declare function getCurationTaskFlowRoutes(options: GetCurationTaskFlowRoutesOptions): RouteObject[];
21
+ //# sourceMappingURL=curationTaskFlowRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curationTaskFlowRoutes.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/curationTaskFlowRoutes.tsx"],"names":[],"mappings":"AASA,OAAO,EAGL,WAAW,EAGZ,MAAM,cAAc,CAAA;AAMrB,MAAM,MAAM,gCAAgC,GAAG;IAC7C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAwFD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,WAAW,EAAE,CAyBf"}
@@ -0,0 +1,100 @@
1
+ import { CREATE_COMPUTE_TASK_PAGE_TITLE as e, CREATE_CURATE_TASK_PAGE_TITLE as t, FILL_IN_COMPUTE_TASK_DETAILS_DESCRIPTION as n, FILL_IN_CURATE_TASK_DETAILS_DESCRIPTION as r } from "../utils/constants.js";
2
+ import i from "./ComputeTaskForm.js";
3
+ import a from "./CreateTaskCategoryPicker.js";
4
+ import o from "./CreateTaskConfirmation.js";
5
+ import s from "./CurateTaskForm.js";
6
+ import { Button as c } from "@mui/material";
7
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
8
+ import { ArrowBack as f } from "@mui/icons-material";
9
+ import { Navigate as p, Outlet as m, useNavigate as h, useParams as g } from "react-router";
10
+ //#region src/features/entity/metadata-task/create-task/curationTaskFlowRoutes.tsx
11
+ function _(e) {
12
+ let { onExit: t } = e;
13
+ return /* @__PURE__ */ d(l, { children: [t && /* @__PURE__ */ u(c, {
14
+ variant: "text",
15
+ startIcon: /* @__PURE__ */ u(f, {}),
16
+ onClick: t,
17
+ sx: { alignSelf: "flex-start" },
18
+ children: "Back to All Tasks"
19
+ }), /* @__PURE__ */ u(m, {})] });
20
+ }
21
+ function v(e) {
22
+ let t = h();
23
+ return /* @__PURE__ */ u(_, { onExit: () => void t(e.exitPath) });
24
+ }
25
+ function y() {
26
+ let e = h();
27
+ return /* @__PURE__ */ u(a, {
28
+ onSelectCompute: () => void e("compute"),
29
+ onSelectCurate: () => void e("curate")
30
+ });
31
+ }
32
+ function b(t) {
33
+ let r = h();
34
+ return /* @__PURE__ */ u(i, {
35
+ projectId: t.projectId,
36
+ pageTitle: e,
37
+ pageDescription: n,
38
+ onBack: () => void r(-1),
39
+ onExit: () => void r(t.exitPath),
40
+ onCreated: (e) => void r(`../confirmation/${e.taskId}`)
41
+ });
42
+ }
43
+ function x(e) {
44
+ let n = h();
45
+ return /* @__PURE__ */ u(s, {
46
+ projectId: e.projectId,
47
+ pageTitle: t,
48
+ pageDescription: r,
49
+ onBack: () => void n(-1),
50
+ onExit: () => void n(e.exitPath),
51
+ onCreated: (e) => void n(`../confirmation/${e.taskId}`)
52
+ });
53
+ }
54
+ function S(e) {
55
+ let { taskId: t } = g(), n = h(), r = t ? Number(t) : void 0;
56
+ return r ? /* @__PURE__ */ u(o, {
57
+ taskId: r,
58
+ onDone: () => void n(e.exitPath)
59
+ }) : /* @__PURE__ */ u(p, {
60
+ to: "..",
61
+ replace: !0
62
+ });
63
+ }
64
+ function C(e) {
65
+ let { projectId: t, exitPath: n } = e;
66
+ return [
67
+ {
68
+ element: /* @__PURE__ */ u(v, { exitPath: n }),
69
+ children: [{
70
+ index: !0,
71
+ element: /* @__PURE__ */ u(y, {})
72
+ }]
73
+ },
74
+ {
75
+ element: /* @__PURE__ */ u(_, {}),
76
+ children: [{
77
+ path: "confirmation/:taskId",
78
+ element: /* @__PURE__ */ u(S, { exitPath: n })
79
+ }]
80
+ },
81
+ {
82
+ path: "compute",
83
+ element: /* @__PURE__ */ u(b, {
84
+ projectId: t,
85
+ exitPath: n
86
+ })
87
+ },
88
+ {
89
+ path: "curate",
90
+ element: /* @__PURE__ */ u(x, {
91
+ projectId: t,
92
+ exitPath: n
93
+ })
94
+ }
95
+ ];
96
+ }
97
+ //#endregion
98
+ export { C as getCurationTaskFlowRoutes };
99
+
100
+ //# sourceMappingURL=curationTaskFlowRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curationTaskFlowRoutes.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/curationTaskFlowRoutes.tsx"],"sourcesContent":["import {\n CREATE_COMPUTE_TASK_PAGE_TITLE,\n CREATE_CURATE_TASK_PAGE_TITLE,\n FILL_IN_COMPUTE_TASK_DETAILS_DESCRIPTION,\n FILL_IN_CURATE_TASK_DETAILS_DESCRIPTION,\n BACK_TO_ALL_TASKS_LABEL,\n} from '../utils/constants'\nimport { ArrowBack } from '@mui/icons-material'\nimport { Button } from '@mui/material'\nimport {\n Navigate,\n Outlet,\n RouteObject,\n useNavigate,\n useParams,\n} from 'react-router'\nimport ComputeTaskForm from './ComputeTaskForm'\nimport CreateTaskCategoryPicker from './CreateTaskCategoryPicker'\nimport CreateTaskConfirmation from './CreateTaskConfirmation'\nimport CurateTaskForm from './CurateTaskForm'\n\nexport type GetCurationTaskFlowRoutesOptions = {\n /**\n * Present when the host page already has a project context (e.g. a project's Metadata Tasks page).\n * Absent when creating from a context without one (e.g. the Curator Dashboard).\n */\n projectId?: string\n /**\n * Path (relative to the host router) to navigate to when the user exits the flow -- via \"Back to\n * All Tasks\" on the category picker/compute/curate forms, or \"Back to All Tasks\" on the\n * confirmation screen. Typically the host's own index route (`'/'`).\n */\n exitPath: string\n}\n\n/**\n * Layout for the steps that share the generic \"Create New Task\" header (the category picker and the\n * confirmation screen). The compute/curate form steps render their own more specific centered\n * title/subtitle instead (via their `pageTitle`/`pageDescription` props below), so they aren't nested\n * under this layout.\n *\n * When `onExit` is provided, a top-left \"Back to All Tasks\" button is shown above the title, matching\n * the one on the form steps.\n */\nfunction CreateTaskLayout(props: { onExit?: () => void }) {\n const { onExit } = props\n return (\n <>\n {onExit && (\n <Button\n variant=\"text\"\n startIcon={<ArrowBack />}\n onClick={onExit}\n sx={{ alignSelf: 'flex-start' }}\n >\n {BACK_TO_ALL_TASKS_LABEL}\n </Button>\n )}\n <Outlet />\n </>\n )\n}\n\nfunction CategoryPickerLayoutRoute(props: { exitPath: string }) {\n const navigate = useNavigate()\n return <CreateTaskLayout onExit={() => void navigate(props.exitPath)} />\n}\n\nfunction CategoryPickerRoute() {\n const navigate = useNavigate()\n return (\n <CreateTaskCategoryPicker\n onSelectCompute={() => void navigate('compute')}\n onSelectCurate={() => void navigate('curate')}\n />\n )\n}\n\nfunction ComputeFormRoute(props: { projectId?: string; exitPath: string }) {\n const navigate = useNavigate()\n return (\n <ComputeTaskForm\n projectId={props.projectId}\n pageTitle={CREATE_COMPUTE_TASK_PAGE_TITLE}\n pageDescription={FILL_IN_COMPUTE_TASK_DETAILS_DESCRIPTION}\n onBack={() => void navigate(-1)}\n onExit={() => void navigate(props.exitPath)}\n onCreated={task => void navigate(`../confirmation/${task.taskId}`)}\n />\n )\n}\n\nfunction CurateFormRoute(props: { projectId?: string; exitPath: string }) {\n const navigate = useNavigate()\n return (\n <CurateTaskForm\n projectId={props.projectId}\n pageTitle={CREATE_CURATE_TASK_PAGE_TITLE}\n pageDescription={FILL_IN_CURATE_TASK_DETAILS_DESCRIPTION}\n onBack={() => void navigate(-1)}\n onExit={() => void navigate(props.exitPath)}\n onCreated={task => void navigate(`../confirmation/${task.taskId}`)}\n />\n )\n}\n\nfunction ConfirmationRoute(props: { exitPath: string }) {\n const { taskId } = useParams<{ taskId: string }>()\n const navigate = useNavigate()\n const parsedTaskId = taskId ? Number(taskId) : undefined\n if (!parsedTaskId) {\n return <Navigate to=\"..\" replace />\n }\n return (\n <CreateTaskConfirmation\n taskId={parsedTaskId}\n onDone={() => void navigate(props.exitPath)}\n />\n )\n}\n\n/**\n * Builds the route objects for the 3-step \"Create New Task\" wizard: category picker -> compute/curate\n * form -> confirmation. The task itself is created on the step-2-to-step-3 transition (see\n * `ComputeTaskForm`/`CurateTaskForm`'s `onCreated`).\n */\nexport function getCurationTaskFlowRoutes(\n options: GetCurationTaskFlowRoutesOptions,\n): RouteObject[] {\n const { projectId, exitPath } = options\n return [\n {\n element: <CategoryPickerLayoutRoute exitPath={exitPath} />,\n children: [{ index: true, element: <CategoryPickerRoute /> }],\n },\n {\n element: <CreateTaskLayout />,\n children: [\n {\n path: 'confirmation/:taskId',\n element: <ConfirmationRoute exitPath={exitPath} />,\n },\n ],\n },\n {\n path: 'compute',\n element: <ComputeFormRoute projectId={projectId} exitPath={exitPath} />,\n },\n {\n path: 'curate',\n element: <CurateFormRoute projectId={projectId} exitPath={exitPath} />,\n },\n ]\n}\n"],"mappings":";;;;;;;;;;AA4CA,SAAS,EAAiB,GAAgC;CACxD,IAAM,EAAE,cAAW;CACnB,OACE,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,GAAD;EACE,SAAQ;EACR,WAAW,kBAAC,GAAD,CAAY,CAAA;EACvB,SAAS;EACT,IAAI,EAAE,WAAW,aAAa;;CAGxB,CAAA,GAEV,kBAAC,GAAD,CAAS,CAAA,CACT,EAAA,CAAA;AAEN;AAEA,SAAS,EAA0B,GAA6B;CAC9D,IAAM,IAAW,EAAY;CAC7B,OAAO,kBAAC,GAAD,EAAkB,cAAc,KAAK,EAAS,EAAM,QAAQ,EAAI,CAAA;AACzE;AAEA,SAAS,IAAsB;CAC7B,IAAM,IAAW,EAAY;CAC7B,OACE,kBAAC,GAAD;EACE,uBAAuB,KAAK,EAAS,SAAS;EAC9C,sBAAsB,KAAK,EAAS,QAAQ;CAC7C,CAAA;AAEL;AAEA,SAAS,EAAiB,GAAiD;CACzE,IAAM,IAAW,EAAY;CAC7B,OACE,kBAAC,GAAD;EACE,WAAW,EAAM;EACjB,WAAW;EACX,iBAAiB;EACjB,cAAc,KAAK,EAAS,EAAE;EAC9B,cAAc,KAAK,EAAS,EAAM,QAAQ;EAC1C,YAAW,MAAQ,KAAK,EAAS,mBAAmB,EAAK,QAAQ;CAClE,CAAA;AAEL;AAEA,SAAS,EAAgB,GAAiD;CACxE,IAAM,IAAW,EAAY;CAC7B,OACE,kBAAC,GAAD;EACE,WAAW,EAAM;EACjB,WAAW;EACX,iBAAiB;EACjB,cAAc,KAAK,EAAS,EAAE;EAC9B,cAAc,KAAK,EAAS,EAAM,QAAQ;EAC1C,YAAW,MAAQ,KAAK,EAAS,mBAAmB,EAAK,QAAQ;CAClE,CAAA;AAEL;AAEA,SAAS,EAAkB,GAA6B;CACtD,IAAM,EAAE,cAAW,EAA8B,GAC3C,IAAW,EAAY,GACvB,IAAe,IAAS,OAAO,CAAM,IAAI,KAAA;CAI/C,OAHK,IAIH,kBAAC,GAAD;EACE,QAAQ;EACR,cAAc,KAAK,EAAS,EAAM,QAAQ;CAC3C,CAAA,IANM,kBAAC,GAAD;EAAU,IAAG;EAAK,SAAA;CAAS,CAAA;AAQtC;AAOA,SAAgB,EACd,GACe;CACf,IAAM,EAAE,cAAW,gBAAa;CAChC,OAAO;EACL;GACE,SAAS,kBAAC,GAAD,EAAqC,YAAW,CAAA;GACzD,UAAU,CAAC;IAAE,OAAO;IAAM,SAAS,kBAAC,GAAD,CAAsB,CAAA;GAAE,CAAC;EAC9D;EACA;GACE,SAAS,kBAAC,GAAD,CAAmB,CAAA;GAC5B,UAAU,CACR;IACE,MAAM;IACN,SAAS,kBAAC,GAAD,EAA6B,YAAW,CAAA;GACnD,CACF;EACF;EACA;GACE,MAAM;GACN,SAAS,kBAAC,GAAD;IAA6B;IAAqB;GAAW,CAAA;EACxE;EACA;GACE,MAAM;GACN,SAAS,kBAAC,GAAD;IAA4B;IAAqB;GAAW,CAAA;EACvE;CACF;AACF"}
@@ -0,0 +1,24 @@
1
+ import { CurationTaskProperties } from '@sage-bionetworks/synapse-client';
2
+ import { ComputeTaskConcreteType } from '../utils/types';
3
+ import { RecordSetFieldsValue } from './RecordSetFields';
4
+ import { SampleSheetFieldsValue } from './SampleSheetFields';
5
+ import { ComputeTypeFields } from './utils/buildComputeTaskPayload';
6
+ export type UseComputeTypeFieldsArgs = {
7
+ /** The existing task's `taskProperties`, for edit-mode initialization. Undefined when creating. */
8
+ taskProperties: CurationTaskProperties | undefined;
9
+ isEditMode: boolean;
10
+ };
11
+ /**
12
+ * Owns the single active Compute Data type-specific value (`ComputeTypeFields`) for `ComputeTaskForm`:
13
+ * which concrete type is selected, its field values, and whether that value is currently valid.
14
+ * Switching the concrete type resets the value to that type's empty default.
15
+ */
16
+ export declare function useComputeTypeFields(args: UseComputeTypeFieldsArgs): {
17
+ state: ComputeTypeFields;
18
+ setConcreteType: (concreteType: ComputeTaskConcreteType) => void;
19
+ setValue: (value: SampleSheetFieldsValue | RecordSetFieldsValue) => void;
20
+ isValid: boolean;
21
+ showTypeSection: boolean;
22
+ showUnrecognizedTypeWarning: boolean;
23
+ };
24
+ //# sourceMappingURL=useComputeTypeFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComputeTypeFields.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useComputeTypeFields.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAGvB,MAAM,kCAAkC,CAAA;AAGzC,OAAO,EACL,uBAAuB,EAGxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAGL,oBAAoB,EACrB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAGL,sBAAsB,EACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AA6CnE,MAAM,MAAM,wBAAwB,GAAG;IACrC,mGAAmG;IACnG,cAAc,EAAE,sBAAsB,GAAG,SAAS,CAAA;IAClD,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB;;oCAiB1B,uBAAuB;sBAIrC,sBAAsB,GAAG,oBAAoB;;;;EAmBvE"}
@@ -0,0 +1,56 @@
1
+ import { DEFAULT_COMPUTE_TASK_TYPE as e } from "../utils/constants.js";
2
+ import { getComputeTaskConcreteType as t, instanceOfGridSupportedTaskProperties as n } from "../utils/types.js";
3
+ import { EMPTY_RECORD_SET_VALUE as r, isRecordSetFieldsValueValid as i } from "./RecordSetFields.js";
4
+ import { EMPTY_SAMPLE_SHEET_VALUE as a, isSampleSheetFieldsValueValid as o } from "./SampleSheetFields.js";
5
+ import { useState as s } from "react";
6
+ import { RecordSetGenerationExecutionPropertiesConcreteTypeEnum as c, SampleSheetGenerationExecutionPropertiesConcreteTypeEnum as l } from "@sage-bionetworks/synapse-client";
7
+ //#region src/features/entity/metadata-task/create-task/useComputeTypeFields.ts
8
+ function u(e) {
9
+ return e === c.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties ? {
10
+ concreteType: e,
11
+ value: r
12
+ } : {
13
+ concreteType: e,
14
+ value: a
15
+ };
16
+ }
17
+ function d(t) {
18
+ return t?.concreteType === l.org_sagebionetworks_repo_model_curation_execution_SampleSheetGenerationExecutionProperties ? {
19
+ concreteType: t.concreteType,
20
+ value: {
21
+ inputTaskId: t.inputTaskId?.toString() ?? "",
22
+ destinationTaskId: t.destinationTaskId?.toString() ?? ""
23
+ }
24
+ } : t?.concreteType === c.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties ? {
25
+ concreteType: t.concreteType,
26
+ value: {
27
+ folderId: t.folderId ?? "",
28
+ instructions: t.instructions ?? "",
29
+ destinationTaskId: t.destinationTaskId?.toString() ?? ""
30
+ }
31
+ } : u(e);
32
+ }
33
+ function f(e) {
34
+ let { taskProperties: r, isEditMode: a } = e, c = t(r), f = !a || c !== void 0, p = a && c === void 0 && !n(r), [m, h] = s(() => d(r));
35
+ function g(e) {
36
+ h(u(e));
37
+ }
38
+ function _(e) {
39
+ h((t) => ({
40
+ ...t,
41
+ value: e
42
+ }));
43
+ }
44
+ return {
45
+ state: m,
46
+ setConcreteType: g,
47
+ setValue: _,
48
+ isValid: !f || (m.concreteType === l.org_sagebionetworks_repo_model_curation_execution_SampleSheetGenerationExecutionProperties ? o(m.value) : i(m.value)),
49
+ showTypeSection: f,
50
+ showUnrecognizedTypeWarning: p
51
+ };
52
+ }
53
+ //#endregion
54
+ export { f as useComputeTypeFields };
55
+
56
+ //# sourceMappingURL=useComputeTypeFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComputeTypeFields.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useComputeTypeFields.ts"],"sourcesContent":["import {\n CurationTaskProperties,\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum,\n SampleSheetGenerationExecutionPropertiesConcreteTypeEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport { DEFAULT_COMPUTE_TASK_TYPE } from '../utils/constants'\nimport {\n ComputeTaskConcreteType,\n getComputeTaskConcreteType,\n instanceOfGridSupportedTaskProperties,\n} from '../utils/types'\nimport {\n EMPTY_RECORD_SET_VALUE,\n isRecordSetFieldsValueValid,\n RecordSetFieldsValue,\n} from './RecordSetFields'\nimport {\n EMPTY_SAMPLE_SHEET_VALUE,\n isSampleSheetFieldsValueValid,\n SampleSheetFieldsValue,\n} from './SampleSheetFields'\nimport { ComputeTypeFields } from './utils/buildComputeTaskPayload'\n\nfunction emptyValueForConcreteType(\n concreteType: ComputeTaskConcreteType,\n): ComputeTypeFields {\n if (\n concreteType ===\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties\n ) {\n return { concreteType, value: EMPTY_RECORD_SET_VALUE }\n }\n return { concreteType, value: EMPTY_SAMPLE_SHEET_VALUE }\n}\n\nfunction initialStateFor(\n taskProperties: CurationTaskProperties | undefined,\n): ComputeTypeFields {\n if (\n taskProperties?.concreteType ===\n SampleSheetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_SampleSheetGenerationExecutionProperties\n ) {\n return {\n concreteType: taskProperties.concreteType,\n value: {\n inputTaskId: taskProperties.inputTaskId?.toString() ?? '',\n destinationTaskId: taskProperties.destinationTaskId?.toString() ?? '',\n },\n }\n }\n if (\n taskProperties?.concreteType ===\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties\n ) {\n return {\n concreteType: taskProperties.concreteType,\n value: {\n folderId: taskProperties.folderId ?? '',\n instructions: taskProperties.instructions ?? '',\n destinationTaskId: taskProperties.destinationTaskId?.toString() ?? '',\n },\n }\n }\n return emptyValueForConcreteType(DEFAULT_COMPUTE_TASK_TYPE)\n}\n\nexport type UseComputeTypeFieldsArgs = {\n /** The existing task's `taskProperties`, for edit-mode initialization. Undefined when creating. */\n taskProperties: CurationTaskProperties | undefined\n isEditMode: boolean\n}\n\n/**\n * Owns the single active Compute Data type-specific value (`ComputeTypeFields`) for `ComputeTaskForm`:\n * which concrete type is selected, its field values, and whether that value is currently valid.\n * Switching the concrete type resets the value to that type's empty default.\n */\nexport function useComputeTypeFields(args: UseComputeTypeFieldsArgs) {\n const { taskProperties, isEditMode } = args\n\n const existingComputeConcreteType = getComputeTaskConcreteType(taskProperties)\n // Whether the type-specific fields (and type selector) should render at all. False when editing a\n // task whose category isn't one of the two Compute Data types (e.g. a legacy Curate Data task).\n const showTypeSection =\n !isEditMode || existingComputeConcreteType !== undefined\n const showUnrecognizedTypeWarning =\n isEditMode &&\n existingComputeConcreteType === undefined &&\n !instanceOfGridSupportedTaskProperties(taskProperties)\n\n const [state, setState] = useState<ComputeTypeFields>(() =>\n initialStateFor(taskProperties),\n )\n\n function setConcreteType(concreteType: ComputeTaskConcreteType) {\n setState(emptyValueForConcreteType(concreteType))\n }\n\n function setValue(value: SampleSheetFieldsValue | RecordSetFieldsValue) {\n setState(prev => ({ ...prev, value }) as ComputeTypeFields)\n }\n\n const isValid =\n !showTypeSection ||\n (state.concreteType ===\n SampleSheetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_SampleSheetGenerationExecutionProperties\n ? isSampleSheetFieldsValueValid(state.value)\n : isRecordSetFieldsValueValid(state.value))\n\n return {\n state,\n setConcreteType,\n setValue,\n isValid,\n showTypeSection,\n showUnrecognizedTypeWarning,\n }\n}\n"],"mappings":";;;;;;;AAwBA,SAAS,EACP,GACmB;CAOnB,OALE,MACA,EAAuD,2FAEhD;EAAE;EAAc,OAAO;CAAuB,IAEhD;EAAE;EAAc,OAAO;CAAyB;AACzD;AAEA,SAAS,EACP,GACmB;CA0BnB,OAxBE,GAAgB,iBAChB,EAAyD,6FAElD;EACL,cAAc,EAAe;EAC7B,OAAO;GACL,aAAa,EAAe,aAAa,SAAS,KAAK;GACvD,mBAAmB,EAAe,mBAAmB,SAAS,KAAK;EACrE;CACF,IAGA,GAAgB,iBAChB,EAAuD,2FAEhD;EACL,cAAc,EAAe;EAC7B,OAAO;GACL,UAAU,EAAe,YAAY;GACrC,cAAc,EAAe,gBAAgB;GAC7C,mBAAmB,EAAe,mBAAmB,SAAS,KAAK;EACrE;CACF,IAEK,EAA0B,CAAyB;AAC5D;AAaA,SAAgB,EAAqB,GAAgC;CACnE,IAAM,EAAE,mBAAgB,kBAAe,GAEjC,IAA8B,EAA2B,CAAc,GAGvE,IACJ,CAAC,KAAc,MAAgC,KAAA,GAC3C,IACJ,KACA,MAAgC,KAAA,KAChC,CAAC,EAAsC,CAAc,GAEjD,CAAC,GAAO,KAAY,QACxB,EAAgB,CAAc,CAChC;CAEA,SAAS,EAAgB,GAAuC;EAC9D,EAAS,EAA0B,CAAY,CAAC;CAClD;CAEA,SAAS,EAAS,GAAsD;EACtE,GAAS,OAAS;GAAE,GAAG;GAAM;EAAM,EAAuB;CAC5D;CASA,OAAO;EACL;EACA;EACA;EACA,SAVA,CAAC,MACA,EAAM,iBACP,EAAyD,6FACrD,EAA8B,EAAM,KAAK,IACzC,EAA4B,EAAM,KAAK;EAO3C;EACA;CACF;AACF"}
@@ -0,0 +1,26 @@
1
+ import { CurationTaskProperties } from '@sage-bionetworks/synapse-client';
2
+ import { CurateTaskConcreteType } from '../utils/types';
3
+ import { FileBasedFieldsValue } from './FileBasedFields';
4
+ import { RecordBasedFieldsValue } from './RecordBasedFields';
5
+ import { CurateTypeState } from './utils/buildCurateTaskPayload';
6
+ export type UseCurateTypeFieldsArgs = {
7
+ /** The existing task's `taskProperties`, for edit-mode initialization. Undefined when creating. */
8
+ taskProperties: CurationTaskProperties | undefined;
9
+ isEditMode: boolean;
10
+ };
11
+ /**
12
+ * Owns the single active Curate Data type-specific value (`CurateTypeState`) for `CurateTaskForm` --
13
+ * which concrete type is selected, its field values, and whether that value is currently valid -- plus
14
+ * the Authorization Mode selection and whether it has changed from the task's existing value.
15
+ * Switching the concrete type resets the value to that type's empty default.
16
+ */
17
+ export declare function useCurateTypeFields(args: UseCurateTypeFieldsArgs): {
18
+ state: CurateTypeState;
19
+ setConcreteType: (concreteType: CurateTaskConcreteType) => void;
20
+ setValue: (value: FileBasedFieldsValue | RecordBasedFieldsValue) => void;
21
+ isValid: boolean;
22
+ authorizationMode: "NONE" | "SESSION_OWNER" | "SOURCE_BENEFACTOR";
23
+ setAuthorizationMode: import("react").Dispatch<import("react").SetStateAction<"NONE" | "SESSION_OWNER" | "SOURCE_BENEFACTOR">>;
24
+ authModeChanged: boolean;
25
+ };
26
+ //# sourceMappingURL=useCurateTypeFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCurateTypeFields.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useCurateTypeFields.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAGvB,MAAM,kCAAkC,CAAA;AAGzC,OAAO,EACL,sBAAsB,EAEvB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAEL,oBAAoB,EAErB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAGL,sBAAsB,EACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAEL,eAAe,EAChB,MAAM,gCAAgC,CAAA;AAgDvC,MAAM,MAAM,uBAAuB,GAAG;IACpC,mGAAmG;IACnG,cAAc,EAAE,sBAAsB,GAAG,SAAS,CAAA;IAClD,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB;;oCAOxB,sBAAsB;sBAIpC,oBAAoB,GAAG,sBAAsB;;;;;EA8BvE"}
@@ -0,0 +1,57 @@
1
+ import { DEFAULT_CURATE_TASK_TYPE as e } from "../utils/constants.js";
2
+ import { instanceOfGridSupportedTaskProperties as t } from "../utils/types.js";
3
+ import { EMPTY_FILE_BASED_VALUE as n, isFileBasedFieldsValueValid as r } from "./FileBasedFields.js";
4
+ import { EMPTY_RECORD_BASED_VALUE as i, isRecordBasedFieldsValueValid as a } from "./RecordBasedFields.js";
5
+ import { useState as o } from "react";
6
+ import { FileBasedMetadataTaskPropertiesConcreteTypeEnum as s, RecordBasedMetadataTaskPropertiesConcreteTypeEnum as c } from "@sage-bionetworks/synapse-client";
7
+ //#region src/features/entity/metadata-task/create-task/useCurateTypeFields.ts
8
+ function l(e) {
9
+ return e === "SESSION_OWNER" || e === "SOURCE_BENEFACTOR" ? e : "NONE";
10
+ }
11
+ function u(e) {
12
+ return e === c.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties ? {
13
+ concreteType: e,
14
+ value: i
15
+ } : {
16
+ concreteType: e,
17
+ value: n
18
+ };
19
+ }
20
+ function d(t) {
21
+ return t?.concreteType === s.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties ? {
22
+ concreteType: t.concreteType,
23
+ value: {
24
+ uploadFolderId: t.uploadFolderId ?? "",
25
+ fileViewId: t.fileViewId ?? ""
26
+ }
27
+ } : t?.concreteType === c.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties ? {
28
+ concreteType: t.concreteType,
29
+ value: { recordSetId: t.recordSetId ?? "" }
30
+ } : u(e);
31
+ }
32
+ function f(e) {
33
+ let { taskProperties: n, isEditMode: i } = e, [c, f] = o(() => d(n));
34
+ function p(e) {
35
+ f(u(e));
36
+ }
37
+ function m(e) {
38
+ f((t) => ({
39
+ ...t,
40
+ value: e
41
+ }));
42
+ }
43
+ let h = c.concreteType === s.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties ? r(c.value) : a(c.value), g = l(t(n) ? n.suggestedAuthorizationMode : void 0), [_, v] = o(g);
44
+ return {
45
+ state: c,
46
+ setConcreteType: p,
47
+ setValue: m,
48
+ isValid: h,
49
+ authorizationMode: _,
50
+ setAuthorizationMode: v,
51
+ authModeChanged: i && _ !== g
52
+ };
53
+ }
54
+ //#endregion
55
+ export { f as useCurateTypeFields };
56
+
57
+ //# sourceMappingURL=useCurateTypeFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCurateTypeFields.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useCurateTypeFields.ts"],"sourcesContent":["import {\n CurationTaskProperties,\n FileBasedMetadataTaskPropertiesConcreteTypeEnum,\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport { DEFAULT_CURATE_TASK_TYPE } from '../utils/constants'\nimport {\n CurateTaskConcreteType,\n instanceOfGridSupportedTaskProperties,\n} from '../utils/types'\nimport {\n EMPTY_FILE_BASED_VALUE,\n FileBasedFieldsValue,\n isFileBasedFieldsValueValid,\n} from './FileBasedFields'\nimport {\n EMPTY_RECORD_BASED_VALUE,\n isRecordBasedFieldsValueValid,\n RecordBasedFieldsValue,\n} from './RecordBasedFields'\nimport {\n AuthorizationModeOption,\n CurateTypeState,\n} from './utils/buildCurateTaskPayload'\n\nfunction toAuthorizationModeOption(\n value: string | undefined,\n): AuthorizationModeOption {\n if (value === 'SESSION_OWNER' || value === 'SOURCE_BENEFACTOR') return value\n return 'NONE'\n}\n\nfunction emptyValueForConcreteType(\n concreteType: CurateTaskConcreteType,\n): CurateTypeState {\n if (\n concreteType ===\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties\n ) {\n return { concreteType, value: EMPTY_RECORD_BASED_VALUE }\n }\n return { concreteType, value: EMPTY_FILE_BASED_VALUE }\n}\n\nfunction initialStateFor(\n taskProperties: CurationTaskProperties | undefined,\n): CurateTypeState {\n if (\n taskProperties?.concreteType ===\n FileBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties\n ) {\n return {\n concreteType: taskProperties.concreteType,\n value: {\n uploadFolderId: taskProperties.uploadFolderId ?? '',\n fileViewId: taskProperties.fileViewId ?? '',\n },\n }\n }\n if (\n taskProperties?.concreteType ===\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties\n ) {\n return {\n concreteType: taskProperties.concreteType,\n value: { recordSetId: taskProperties.recordSetId ?? '' },\n }\n }\n return emptyValueForConcreteType(DEFAULT_CURATE_TASK_TYPE)\n}\n\nexport type UseCurateTypeFieldsArgs = {\n /** The existing task's `taskProperties`, for edit-mode initialization. Undefined when creating. */\n taskProperties: CurationTaskProperties | undefined\n isEditMode: boolean\n}\n\n/**\n * Owns the single active Curate Data type-specific value (`CurateTypeState`) for `CurateTaskForm` --\n * which concrete type is selected, its field values, and whether that value is currently valid -- plus\n * the Authorization Mode selection and whether it has changed from the task's existing value.\n * Switching the concrete type resets the value to that type's empty default.\n */\nexport function useCurateTypeFields(args: UseCurateTypeFieldsArgs) {\n const { taskProperties, isEditMode } = args\n\n const [state, setState] = useState<CurateTypeState>(() =>\n initialStateFor(taskProperties),\n )\n\n function setConcreteType(concreteType: CurateTaskConcreteType) {\n setState(emptyValueForConcreteType(concreteType))\n }\n\n function setValue(value: FileBasedFieldsValue | RecordBasedFieldsValue) {\n setState(prev => ({ ...prev, value }) as CurateTypeState)\n }\n\n const isValid =\n state.concreteType ===\n FileBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties\n ? isFileBasedFieldsValueValid(state.value)\n : isRecordBasedFieldsValueValid(state.value)\n\n const initialAuthorizationMode = toAuthorizationModeOption(\n instanceOfGridSupportedTaskProperties(taskProperties)\n ? taskProperties.suggestedAuthorizationMode\n : undefined,\n )\n const [authorizationMode, setAuthorizationMode] = useState(\n initialAuthorizationMode,\n )\n const authModeChanged =\n isEditMode && authorizationMode !== initialAuthorizationMode\n\n return {\n state,\n setConcreteType,\n setValue,\n isValid,\n authorizationMode,\n setAuthorizationMode,\n authModeChanged,\n }\n}\n"],"mappings":";;;;;;;AA0BA,SAAS,EACP,GACyB;CAEzB,OADI,MAAU,mBAAmB,MAAU,sBAA4B,IAChE;AACT;AAEA,SAAS,EACP,GACiB;CAOjB,OALE,MACA,EAAkD,qFAE3C;EAAE;EAAc,OAAO;CAAyB,IAElD;EAAE;EAAc,OAAO;CAAuB;AACvD;AAEA,SAAS,EACP,GACiB;CAsBjB,OApBE,GAAgB,iBAChB,EAAgD,mFAEzC;EACL,cAAc,EAAe;EAC7B,OAAO;GACL,gBAAgB,EAAe,kBAAkB;GACjD,YAAY,EAAe,cAAc;EAC3C;CACF,IAGA,GAAgB,iBAChB,EAAkD,qFAE3C;EACL,cAAc,EAAe;EAC7B,OAAO,EAAE,aAAa,EAAe,eAAe,GAAG;CACzD,IAEK,EAA0B,CAAwB;AAC3D;AAcA,SAAgB,EAAoB,GAA+B;CACjE,IAAM,EAAE,mBAAgB,kBAAe,GAEjC,CAAC,GAAO,KAAY,QACxB,EAAgB,CAAc,CAChC;CAEA,SAAS,EAAgB,GAAsC;EAC7D,EAAS,EAA0B,CAAY,CAAC;CAClD;CAEA,SAAS,EAAS,GAAsD;EACtE,GAAS,OAAS;GAAE,GAAG;GAAM;EAAM,EAAqB;CAC1D;CAEA,IAAM,IACJ,EAAM,iBACN,EAAgD,mFAC5C,EAA4B,EAAM,KAAK,IACvC,EAA8B,EAAM,KAAK,GAEzC,IAA2B,EAC/B,EAAsC,CAAc,IAChD,EAAe,6BACf,KAAA,CACN,GACM,CAAC,GAAmB,KAAwB,EAChD,CACF;CAIA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA,iBATA,KAAc,MAAsB;CAUtC;AACF"}
@@ -1,4 +1,4 @@
1
- import { CurationTask, TaskStatusStateEnum } from '@sage-bionetworks/synapse-client';
1
+ import { CurationTask, TaskExecutionDetails, TaskStatusStateEnum } from '@sage-bionetworks/synapse-client';
2
2
  export type UseCurationTaskFormStateArgs = {
3
3
  /**
4
4
  * Present when the host page already has a project context. Absent when creating from a context
@@ -45,6 +45,8 @@ export declare function useCurationTaskFormState(args: UseCurationTaskFormStateA
45
45
  error: import("@sage-bionetworks/synapse-client").SynapseClientError | null;
46
46
  isCommonFieldsValid: boolean;
47
47
  isProjectValid: boolean;
48
- submitTaskAndStatus: (payload: CurationTask) => Promise<CurationTask>;
48
+ submitTaskAndStatus: (payload: CurationTask, options?: {
49
+ initialExecutionDetails?: TaskExecutionDetails;
50
+ }) => Promise<CurationTask>;
49
51
  };
50
52
  //# sourceMappingURL=useCurationTaskFormState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCurationTaskFormState.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,mBAAmB,EACpB,MAAM,kCAAkC,CAAA;AASzC,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmG9D,YAAY,KACpB,OAAO,CAAC,YAAY,CAAC;EA8FzB"}
1
+ {"version":3,"file":"useCurationTaskFormState.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,kCAAkC,CAAA;AASzC,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAoG9D,YAAY,YACX;QAAE,uBAAuB,CAAC,EAAE,oBAAoB,CAAA;KAAE,KAC3D,OAAO,CAAC,YAAY,CAAC;EAkGzB"}
@@ -17,28 +17,29 @@ function p(p) {
17
17
  e(l + t.message, "danger");
18
18
  }
19
19
  }), Q = H || G || J || Z, $ = U ?? K ?? Y, te = !!C.trim() && !!T.trim(), ne = !y || !!b.trim();
20
- async function re(t) {
21
- let n = ee(I);
20
+ async function re(t, n) {
21
+ let r = ee(I);
22
22
  if (_) {
23
- let e = await W(t), r = j !== void 0 && j !== k?.state, i = P !== void 0 && n !== (k?.dueDate ?? void 0);
24
- return (r || i) && k != null && await q({
23
+ let e = await W(t), n = j !== void 0 && j !== k?.state, i = P !== void 0 && r !== (k?.dueDate ?? void 0);
24
+ return (n || i) && k != null && await q({
25
25
  ...k,
26
26
  state: j ?? k.state,
27
- dueDate: P === void 0 ? k.dueDate : n,
27
+ dueDate: P === void 0 ? k.dueDate : r,
28
28
  etag: e.etag
29
29
  }), e;
30
30
  }
31
- let r = await V(t);
32
- if (n && r.taskId != null) try {
31
+ let i = await V(t);
32
+ if ((r || n?.initialExecutionDetails) && i.taskId != null) try {
33
33
  await q({
34
- ...await v.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus({ taskId: r.taskId }),
35
- taskId: r.taskId,
36
- dueDate: n
34
+ ...await v.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus({ taskId: i.taskId }),
35
+ taskId: i.taskId,
36
+ dueDate: r,
37
+ executionDetails: n?.initialExecutionDetails
37
38
  });
38
39
  } catch {
39
40
  e(c, "warning");
40
41
  }
41
- return r;
42
+ return i;
42
43
  }
43
44
  return {
44
45
  isEditMode: _,
@@ -1 +1 @@
1
- {"version":3,"file":"useCurationTaskFormState.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"sourcesContent":["import {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { displayToast } from '@/components/ToastMessage'\nimport { useSynapseContext } from '@/utils/index'\nimport {\n CurationTask,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport {\n CREATE_TASK_STATUS_NOT_SAVED_WARNING,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n} from '../utils/constants'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type UseCurationTaskFormStateArgs = {\n /**\n * Present when the host page already has a project context. Absent when creating from a context\n * without one, in which case the caller renders a project selector. Ignored in edit mode -- the\n * project is always derived from `task`.\n */\n projectId?: string\n /** The task being edited. Undefined when creating a new task. */\n task?: CurationTask\n /** Called after the task is successfully deleted (edit mode only). */\n onDeleted?: () => void\n}\n\n/**\n * The state and persistence logic shared by every curation-task create/edit form\n * (`ComputeTaskForm`, `CurateTaskForm`): common fields, project selection, task status (state +\n * due date), permissions, the create/update/delete mutations, and the submit-with-status flow.\n * The type-specific fields, validity, and payload construction remain the responsibility of each\n * form -- the caller passes a fully-built `CurationTask` payload to `submitTaskAndStatus`.\n */\nexport function useCurationTaskFormState(args: UseCurationTaskFormStateArgs) {\n const { projectId, task, onDeleted } = args\n const isEditMode = task !== undefined\n const { synapseClient } = useSynapseContext()\n\n const showProjectSelector = !isEditMode && !projectId\n const [selectedProjectId, setSelectedProjectId] = useState('')\n const effectiveProjectId = isEditMode\n ? (task?.projectId ?? '')\n : (projectId ?? selectedProjectId)\n\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n // Task status (edit mode only). `dueDate` also lives on TaskStatus, so it's collected here even in\n // create mode (where there's no status to fetch yet -- it's applied to the auto-created status\n // immediately after the task itself is created, see `submitTaskAndStatus`).\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n // `pendingDueDate` and `displayedDueDate` are always the native date input's `YYYY-MM-DD` string.\n // The backend stores `TaskStatus.dueDate` as an ISO 8601 date-time string, so the fetched value is\n // converted for display and the entered value is converted back on write.\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ??\n (isEditMode ? isoToDueDateInput(currentTaskStatus?.dueDate) : '')\n\n const { data: permissions } = useGetEntityPermissions(effectiveProjectId, {\n enabled: !!effectiveProjectId,\n })\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n const canDelete = Boolean(\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n onDeleted != null,\n )\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleted?.()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isStatusUpdatePending ||\n isDeletePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isCommonFieldsValid = !!dataType.trim() && !!instructions.trim()\n const isProjectValid = !showProjectSelector || !!selectedProjectId.trim()\n\n /**\n * Persists `payload` as either a create or an update (based on edit mode), then reconciles the\n * task's `TaskStatus` (state + due date). Returns the persisted task. On create, the status is\n * fetched (it is created server-side automatically) and patched only when a due date was entered.\n * On update, the status is written only when the state or due date changed; clearing the due date\n * (empty string) is a valid change and persists as an absent due date.\n */\n async function submitTaskAndStatus(\n payload: CurationTask,\n ): Promise<CurationTask> {\n const dueDateIso = dueDateInputToIso(displayedDueDate)\n\n if (isEditMode) {\n const latestTask = await updateTask(payload)\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n const dueDateChanged =\n pendingDueDate !== undefined &&\n dueDateIso !== (currentTaskStatus?.dueDate ?? undefined)\n if ((statusStateChanged || dueDateChanged) && currentTaskStatus != null) {\n // The task and its status share an etag, and the preceding `updateTask` bumped it; the\n // status update must use the etag returned by that update, not the stale fetched one. When\n // the user didn't touch the due date, preserve the stored value verbatim rather than the\n // re-encoded one, so a status-only edit can never blank out or rewrite an existing due date.\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n dueDate:\n pendingDueDate !== undefined\n ? dueDateIso\n : currentTaskStatus.dueDate,\n etag: latestTask.etag,\n })\n }\n\n return latestTask\n }\n\n const created = await createTask(payload)\n\n if (dueDateIso && created.taskId != null) {\n // TODO(PLFM-9839): replace this best-effort status write with a single service that creates\n // the task and its status atomically. Until then, the task is created first and the due date\n // is applied to the auto-created status in a separate call; a failure there must not strand a\n // created task or surface as a hard error (which would tempt the user to re-create the task).\n try {\n // A CurationTask's TaskStatus is created automatically server-side; fetch it so the due date\n // can be applied to it. The freshly-fetched status carries the current shared etag.\n const status =\n await synapseClient.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus(\n { taskId: created.taskId },\n )\n await updateTaskStatus({\n ...status,\n taskId: created.taskId,\n dueDate: dueDateIso,\n })\n } catch {\n displayToast(CREATE_TASK_STATUS_NOT_SAVED_WARNING, 'warning')\n }\n }\n\n return created\n }\n\n return {\n isEditMode,\n // project\n showProjectSelector,\n selectedProjectId,\n setSelectedProjectId,\n effectiveProjectId,\n // common fields\n dataType,\n setDataType,\n instructions,\n setInstructions,\n assigneePrincipalId,\n setAssigneePrincipalId,\n // status + due date\n currentTaskStatus,\n isStatusFetching,\n displayedStatusState,\n setPendingStatusState,\n displayedDueDate,\n setPendingDueDate,\n // permissions + delete\n canDelete,\n showDeleteConfirmation,\n setShowDeleteConfirmation,\n deleteTask,\n isDeletePending,\n // aggregate mutation state\n isPending,\n error,\n // validity (common portion; type-specific validity is the caller's responsibility)\n isCommonFieldsValid,\n isProjectValid,\n // submit\n submitTaskAndStatus,\n }\n}\n"],"mappings":";;;;;;;;;;AA0CA,SAAgB,EAAyB,GAAoC;CAC3E,IAAM,EAAE,cAAW,SAAM,iBAAc,GACjC,IAAa,MAAS,KAAA,GACtB,EAAE,qBAAkB,EAAkB,GAEtC,IAAsB,CAAC,KAAc,CAAC,GACtC,CAAC,GAAmB,KAAwB,EAAS,EAAE,GACvD,IAAqB,IACtB,GAAM,aAAa,KACnB,KAAa,GAEZ,CAAC,GAAU,KAAe,QAAe,GAAM,YAAY,EAAE,GAC7D,CAAC,GAAc,KAAmB,QAChC,GAAM,gBAAgB,EAC9B,GACM,CAAC,GAAqB,KAA0B,QAE9C,GAAM,mBAAmB,GAK3B,EAAE,MAAM,GAAmB,YAAY,MAC3C,EAAyB,GAAM,UAAU,GAAG,EAC1C,SAAS,KAAc,GAAM,UAAU,KACzC,CAAC,GACG,CAAC,GAAoB,KAAyB,EAElD,KAAA,CAAS,GACL,IAAuB,KAAsB,GAAmB,OAIhE,CAAC,GAAgB,KAAqB,EAC1C,KAAA,CACF,GACM,IACJ,MACC,IAAa,EAAkB,GAAmB,OAAO,IAAI,KAE1D,EAAE,MAAM,MAAgB,EAAwB,GAAoB,EACxE,SAAS,CAAC,CAAC,EACb,CAAC,GACK,CAAC,GAAwB,KAA6B,EAAS,EAAK,GACpE,IAAY,GAChB,GAAa,aACb,KACA,GAAM,UAAU,QAChB,KAAa,OAGT,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAA4B,GAC1B,EAAE,QAAQ,GAAY,WAAW,MACrC,EAAsB;EACpB,iBAAiB;GAGf,AAFA,EAAa,GAAoC,SAAS,GAC1D,EAA0B,EAAK,GAC/B,IAAY;EACd;EACA,UAAS,MAAO;GACd,EACE,IAA0C,EAAI,SAC9C,QACF;EACF;CACF,CAAC,GAEG,IACJ,KACA,KACA,KACA,GACI,IAAQ,KAAe,KAAe,GAEtC,KAAsB,CAAC,CAAC,EAAS,KAAK,KAAK,CAAC,CAAC,EAAa,KAAK,GAC/D,KAAiB,CAAC,KAAuB,CAAC,CAAC,EAAkB,KAAK;CASxE,eAAe,GACb,GACuB;EACvB,IAAM,IAAa,GAAkB,CAAgB;EAErD,IAAI,GAAY;GACd,IAAM,IAAa,MAAM,EAAW,CAAO,GAErC,IACJ,MAAuB,KAAA,KACvB,MAAuB,GAAmB,OACtC,IACJ,MAAmB,KAAA,KACnB,OAAgB,GAAmB,WAAW,KAAA;GAiBhD,QAhBK,KAAsB,MAAmB,KAAqB,QAKjE,MAAM,EAAiB;IACrB,GAAG;IACH,OAAO,KAAsB,EAAkB;IAC/C,SACE,MAAmB,KAAA,IAEf,EAAkB,UADlB;IAEN,MAAM,EAAW;GACnB,CAAC,GAGI;EACT;EAEA,IAAM,IAAU,MAAM,EAAW,CAAO;EAExC,IAAI,KAAc,EAAQ,UAAU,MAKlC,IAAI;GAOF,MAAM,EAAiB;IACrB,GAAG,MAJG,EAAc,2BAA2B,kCAC7C,EAAE,QAAQ,EAAQ,OAAO,CAC3B;IAGA,QAAQ,EAAQ;IAChB,SAAS;GACX,CAAC;EACH,QAAQ;GACN,EAAa,GAAsC,SAAS;EAC9D;EAGF,OAAO;CACT;CAEA,OAAO;EACL;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EAEA;CACF;AACF"}
1
+ {"version":3,"file":"useCurationTaskFormState.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"sourcesContent":["import {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { displayToast } from '@/components/ToastMessage'\nimport { useSynapseContext } from '@/utils/index'\nimport {\n CurationTask,\n TaskExecutionDetails,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport {\n CREATE_TASK_STATUS_NOT_SAVED_WARNING,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n} from '../utils/constants'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type UseCurationTaskFormStateArgs = {\n /**\n * Present when the host page already has a project context. Absent when creating from a context\n * without one, in which case the caller renders a project selector. Ignored in edit mode -- the\n * project is always derived from `task`.\n */\n projectId?: string\n /** The task being edited. Undefined when creating a new task. */\n task?: CurationTask\n /** Called after the task is successfully deleted (edit mode only). */\n onDeleted?: () => void\n}\n\n/**\n * The state and persistence logic shared by every curation-task create/edit form\n * (`ComputeTaskForm`, `CurateTaskForm`): common fields, project selection, task status (state +\n * due date), permissions, the create/update/delete mutations, and the submit-with-status flow.\n * The type-specific fields, validity, and payload construction remain the responsibility of each\n * form -- the caller passes a fully-built `CurationTask` payload to `submitTaskAndStatus`.\n */\nexport function useCurationTaskFormState(args: UseCurationTaskFormStateArgs) {\n const { projectId, task, onDeleted } = args\n const isEditMode = task !== undefined\n const { synapseClient } = useSynapseContext()\n\n const showProjectSelector = !isEditMode && !projectId\n const [selectedProjectId, setSelectedProjectId] = useState('')\n const effectiveProjectId = isEditMode\n ? (task?.projectId ?? '')\n : (projectId ?? selectedProjectId)\n\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n // Task status (edit mode only). `dueDate` also lives on TaskStatus, so it's collected here even in\n // create mode (where there's no status to fetch yet -- it's applied to the auto-created status\n // immediately after the task itself is created, see `submitTaskAndStatus`).\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n // `pendingDueDate` and `displayedDueDate` are always the native date input's `YYYY-MM-DD` string.\n // The backend stores `TaskStatus.dueDate` as an ISO 8601 date-time string, so the fetched value is\n // converted for display and the entered value is converted back on write.\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ??\n (isEditMode ? isoToDueDateInput(currentTaskStatus?.dueDate) : '')\n\n const { data: permissions } = useGetEntityPermissions(effectiveProjectId, {\n enabled: !!effectiveProjectId,\n })\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n const canDelete = Boolean(\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n onDeleted != null,\n )\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleted?.()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isStatusUpdatePending ||\n isDeletePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isCommonFieldsValid = !!dataType.trim() && !!instructions.trim()\n const isProjectValid = !showProjectSelector || !!selectedProjectId.trim()\n\n /**\n * Persists `payload` as either a create or an update (based on edit mode), then reconciles the\n * task's `TaskStatus` (state + due date + `options.initialExecutionDetails`). Returns the persisted\n * task. On create, the status is fetched (it is created server-side automatically) and patched when\n * a due date was entered or `options.initialExecutionDetails` was supplied. On update, the status is\n * written only when the state or due date changed; clearing the due date (empty string) is a valid\n * change and persists as an absent due date. `initialExecutionDetails` is never backfilled on edit.\n */\n async function submitTaskAndStatus(\n payload: CurationTask,\n options?: { initialExecutionDetails?: TaskExecutionDetails },\n ): Promise<CurationTask> {\n const dueDateIso = dueDateInputToIso(displayedDueDate)\n\n if (isEditMode) {\n const latestTask = await updateTask(payload)\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n const dueDateChanged =\n pendingDueDate !== undefined &&\n dueDateIso !== (currentTaskStatus?.dueDate ?? undefined)\n if ((statusStateChanged || dueDateChanged) && currentTaskStatus != null) {\n // The task and its status share an etag, and the preceding `updateTask` bumped it; the\n // status update must use the etag returned by that update, not the stale fetched one. When\n // the user didn't touch the due date, preserve the stored value verbatim rather than the\n // re-encoded one, so a status-only edit can never blank out or rewrite an existing due date.\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n dueDate:\n pendingDueDate !== undefined\n ? dueDateIso\n : currentTaskStatus.dueDate,\n etag: latestTask.etag,\n })\n }\n\n return latestTask\n }\n\n const created = await createTask(payload)\n\n if (\n (dueDateIso || options?.initialExecutionDetails) &&\n created.taskId != null\n ) {\n // TODO(PLFM-9839): replace this best-effort status write with a single service that creates\n // the task and its status atomically. Until then, the task is created first and the due date\n // is applied to the auto-created status in a separate call; a failure there must not strand a\n // created task or surface as a hard error (which would tempt the user to re-create the task).\n try {\n // A CurationTask's TaskStatus is created automatically server-side; fetch it so the due date\n // can be applied to it. The freshly-fetched status carries the current shared etag.\n const status =\n await synapseClient.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus(\n { taskId: created.taskId },\n )\n await updateTaskStatus({\n ...status,\n taskId: created.taskId,\n dueDate: dueDateIso,\n executionDetails: options?.initialExecutionDetails,\n })\n } catch {\n displayToast(CREATE_TASK_STATUS_NOT_SAVED_WARNING, 'warning')\n }\n }\n\n return created\n }\n\n return {\n isEditMode,\n // project\n showProjectSelector,\n selectedProjectId,\n setSelectedProjectId,\n effectiveProjectId,\n // common fields\n dataType,\n setDataType,\n instructions,\n setInstructions,\n assigneePrincipalId,\n setAssigneePrincipalId,\n // status + due date\n currentTaskStatus,\n isStatusFetching,\n displayedStatusState,\n setPendingStatusState,\n displayedDueDate,\n setPendingDueDate,\n // permissions + delete\n canDelete,\n showDeleteConfirmation,\n setShowDeleteConfirmation,\n deleteTask,\n isDeletePending,\n // aggregate mutation state\n isPending,\n error,\n // validity (common portion; type-specific validity is the caller's responsibility)\n isCommonFieldsValid,\n isProjectValid,\n // submit\n submitTaskAndStatus,\n }\n}\n"],"mappings":";;;;;;;;;;AA2CA,SAAgB,EAAyB,GAAoC;CAC3E,IAAM,EAAE,cAAW,SAAM,iBAAc,GACjC,IAAa,MAAS,KAAA,GACtB,EAAE,qBAAkB,EAAkB,GAEtC,IAAsB,CAAC,KAAc,CAAC,GACtC,CAAC,GAAmB,KAAwB,EAAS,EAAE,GACvD,IAAqB,IACtB,GAAM,aAAa,KACnB,KAAa,GAEZ,CAAC,GAAU,KAAe,QAAe,GAAM,YAAY,EAAE,GAC7D,CAAC,GAAc,KAAmB,QAChC,GAAM,gBAAgB,EAC9B,GACM,CAAC,GAAqB,KAA0B,QAE9C,GAAM,mBAAmB,GAK3B,EAAE,MAAM,GAAmB,YAAY,MAC3C,EAAyB,GAAM,UAAU,GAAG,EAC1C,SAAS,KAAc,GAAM,UAAU,KACzC,CAAC,GACG,CAAC,GAAoB,KAAyB,EAElD,KAAA,CAAS,GACL,IAAuB,KAAsB,GAAmB,OAIhE,CAAC,GAAgB,KAAqB,EAC1C,KAAA,CACF,GACM,IACJ,MACC,IAAa,EAAkB,GAAmB,OAAO,IAAI,KAE1D,EAAE,MAAM,MAAgB,EAAwB,GAAoB,EACxE,SAAS,CAAC,CAAC,EACb,CAAC,GACK,CAAC,GAAwB,KAA6B,EAAS,EAAK,GACpE,IAAY,GAChB,GAAa,aACb,KACA,GAAM,UAAU,QAChB,KAAa,OAGT,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAA4B,GAC1B,EAAE,QAAQ,GAAY,WAAW,MACrC,EAAsB;EACpB,iBAAiB;GAGf,AAFA,EAAa,GAAoC,SAAS,GAC1D,EAA0B,EAAK,GAC/B,IAAY;EACd;EACA,UAAS,MAAO;GACd,EACE,IAA0C,EAAI,SAC9C,QACF;EACF;CACF,CAAC,GAEG,IACJ,KACA,KACA,KACA,GACI,IAAQ,KAAe,KAAe,GAEtC,KAAsB,CAAC,CAAC,EAAS,KAAK,KAAK,CAAC,CAAC,EAAa,KAAK,GAC/D,KAAiB,CAAC,KAAuB,CAAC,CAAC,EAAkB,KAAK;CAUxE,eAAe,GACb,GACA,GACuB;EACvB,IAAM,IAAa,GAAkB,CAAgB;EAErD,IAAI,GAAY;GACd,IAAM,IAAa,MAAM,EAAW,CAAO,GAErC,IACJ,MAAuB,KAAA,KACvB,MAAuB,GAAmB,OACtC,IACJ,MAAmB,KAAA,KACnB,OAAgB,GAAmB,WAAW,KAAA;GAiBhD,QAhBK,KAAsB,MAAmB,KAAqB,QAKjE,MAAM,EAAiB;IACrB,GAAG;IACH,OAAO,KAAsB,EAAkB;IAC/C,SACE,MAAmB,KAAA,IAEf,EAAkB,UADlB;IAEN,MAAM,EAAW;GACnB,CAAC,GAGI;EACT;EAEA,IAAM,IAAU,MAAM,EAAW,CAAO;EAExC,KACG,KAAc,GAAS,4BACxB,EAAQ,UAAU,MAMlB,IAAI;GAOF,MAAM,EAAiB;IACrB,GAAG,MAJG,EAAc,2BAA2B,kCAC7C,EAAE,QAAQ,EAAQ,OAAO,CAC3B;IAGA,QAAQ,EAAQ;IAChB,SAAS;IACT,kBAAkB,GAAS;GAC7B,CAAC;EACH,QAAQ;GACN,EAAa,GAAsC,SAAS;EAC9D;EAGF,OAAO;CACT;CAEA,OAAO;EACL;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EAEA;CACF;AACF"}
@@ -1,18 +1,13 @@
1
- import { CurationTask } from '@sage-bionetworks/synapse-client';
2
- import { ComputeTaskConcreteType } from '../../utils/types';
3
- export type SampleSheetFieldsValue = {
4
- inputTaskId: string;
5
- destinationTaskId: string;
6
- };
7
- export type RecordSetFieldsValue = {
8
- folderId: string;
9
- instructions: string;
10
- destinationTaskId: string;
11
- };
1
+ import { CurationTask, RecordSetGenerationExecutionPropertiesConcreteTypeEnum, SampleSheetGenerationExecutionPropertiesConcreteTypeEnum } from '@sage-bionetworks/synapse-client';
2
+ import { RecordSetFieldsValue } from '../RecordSetFields';
3
+ import { SampleSheetFieldsValue } from '../SampleSheetFields';
4
+ /** A form's active Compute Data type-specific value, as a discriminated union keyed by `concreteType`. */
12
5
  export type ComputeTypeFields = {
13
- concreteType: ComputeTaskConcreteType;
14
- sampleSheet: SampleSheetFieldsValue;
15
- recordSet: RecordSetFieldsValue;
6
+ concreteType: SampleSheetGenerationExecutionPropertiesConcreteTypeEnum;
7
+ value: SampleSheetFieldsValue;
8
+ } | {
9
+ concreteType: RecordSetGenerationExecutionPropertiesConcreteTypeEnum;
10
+ value: RecordSetFieldsValue;
16
11
  };
17
12
  export type BuildComputeTaskPayloadArgs = {
18
13
  /** The task being edited, if any. Server-managed fields (taskId, etag, etc.) are carried over. */
@@ -1 +1 @@
1
- {"version":3,"file":"buildComputeTaskPayload.d.ts","sourceRoot":"","sources":["../../../../../../src/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGb,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAG3D,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,EAAE,uBAAuB,CAAA;IACrC,WAAW,EAAE,sBAAsB,CAAA;IACnC,SAAS,EAAE,oBAAoB,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,kGAAkG;IAClG,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;CACtC,CAAA;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,2BAA2B,GAChC,YAAY,CAsBd"}
1
+ {"version":3,"file":"buildComputeTaskPayload.d.ts","sourceRoot":"","sources":["../../../../../../src/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,sDAAsD,EACtD,wDAAwD,EACzD,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAG7D,0GAA0G;AAC1G,MAAM,MAAM,iBAAiB,GACzB;IACE,YAAY,EAAE,wDAAwD,CAAA;IACtE,KAAK,EAAE,sBAAsB,CAAA;CAC9B,GACD;IACE,YAAY,EAAE,sDAAsD,CAAA;IACpE,KAAK,EAAE,oBAAoB,CAAA;CAC5B,CAAA;AAEL,MAAM,MAAM,2BAA2B,GAAG;IACxC,kGAAkG;IAClG,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;CACtC,CAAA;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,2BAA2B,GAChC,YAAY,CAsBd"}
@@ -13,13 +13,17 @@ function n(e) {
13
13
  };
14
14
  }
15
15
  function r(n) {
16
- let { concreteType: r, sampleSheet: i, recordSet: a } = n;
17
- return r === t.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties ? {
18
- concreteType: r,
19
- folderId: a.folderId.trim() || void 0,
20
- instructions: a.instructions.trim() || void 0,
21
- destinationTaskId: e(a.destinationTaskId)
22
- } : {
16
+ if (n.concreteType === t.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties) {
17
+ let { concreteType: t, value: r } = n;
18
+ return {
19
+ concreteType: t,
20
+ folderId: r.folderId.trim() || void 0,
21
+ instructions: r.instructions.trim() || void 0,
22
+ destinationTaskId: e(r.destinationTaskId)
23
+ };
24
+ }
25
+ let { concreteType: r, value: i } = n;
26
+ return {
23
27
  concreteType: r,
24
28
  inputTaskId: e(i.inputTaskId),
25
29
  destinationTaskId: e(i.destinationTaskId)
@@ -1 +1 @@
1
- {"version":3,"file":"buildComputeTaskPayload.js","names":[],"sources":["../../../../../../src/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.ts"],"sourcesContent":["import {\n CurationTask,\n CurationTaskProperties,\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { ComputeTaskConcreteType } from '../../utils/types'\nimport { parseTaskIdInput } from './taskIdValidation'\n\nexport type SampleSheetFieldsValue = {\n inputTaskId: string\n destinationTaskId: string\n}\n\nexport type RecordSetFieldsValue = {\n folderId: string\n instructions: string\n destinationTaskId: string\n}\n\nexport type ComputeTypeFields = {\n concreteType: ComputeTaskConcreteType\n sampleSheet: SampleSheetFieldsValue\n recordSet: RecordSetFieldsValue\n}\n\nexport type BuildComputeTaskPayloadArgs = {\n /** The task being edited, if any. Server-managed fields (taskId, etag, etc.) are carried over. */\n existingTask?: CurationTask\n projectId: string\n dataType: string\n instructions: string\n assigneePrincipalId: string | undefined\n /**\n * The Compute Data type-specific fields to write into `taskProperties`. Omit this when editing a task\n * whose category is not one of the two Compute Data types (e.g. a legacy Curate Data task) -- in that\n * case the existing `taskProperties` are carried over unchanged.\n */\n computeTypeFields?: ComputeTypeFields\n}\n\n/**\n * Builds the `CurationTask` payload for creating or updating a Compute Data task from the create/edit\n * task form's field state.\n */\nexport function buildComputeTaskPayload(\n args: BuildComputeTaskPayloadArgs,\n): CurationTask {\n const {\n existingTask,\n projectId,\n dataType,\n instructions,\n assigneePrincipalId,\n computeTypeFields,\n } = args\n\n const taskProperties = computeTypeFields\n ? buildComputeTaskProperties(computeTypeFields)\n : existingTask?.taskProperties\n\n return {\n ...existingTask,\n projectId,\n dataType: dataType.trim() || undefined,\n instructions: instructions.trim() || undefined,\n assigneePrincipalId: assigneePrincipalId || undefined,\n taskProperties,\n }\n}\n\nfunction buildComputeTaskProperties(\n fields: ComputeTypeFields,\n): CurationTaskProperties {\n const { concreteType, sampleSheet, recordSet } = fields\n\n if (\n concreteType ===\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties\n ) {\n return {\n concreteType,\n folderId: recordSet.folderId.trim() || undefined,\n instructions: recordSet.instructions.trim() || undefined,\n destinationTaskId: parseTaskIdInput(recordSet.destinationTaskId),\n }\n }\n\n return {\n concreteType,\n inputTaskId: parseTaskIdInput(sampleSheet.inputTaskId),\n destinationTaskId: parseTaskIdInput(sampleSheet.destinationTaskId),\n }\n}\n"],"mappings":";;;AA4CA,SAAgB,EACd,GACc;CACd,IAAM,EACJ,iBACA,cACA,aACA,iBACA,wBACA,yBACE,GAEE,IAAiB,IACnB,EAA2B,CAAiB,IAC5C,GAAc;CAElB,OAAO;EACL,GAAG;EACH;EACA,UAAU,EAAS,KAAK,KAAK,KAAA;EAC7B,cAAc,EAAa,KAAK,KAAK,KAAA;EACrC,qBAAqB,KAAuB,KAAA;EAC5C;CACF;AACF;AAEA,SAAS,EACP,GACwB;CACxB,IAAM,EAAE,iBAAc,gBAAa,iBAAc;CAcjD,OAXE,MACA,EAAuD,2FAEhD;EACL;EACA,UAAU,EAAU,SAAS,KAAK,KAAK,KAAA;EACvC,cAAc,EAAU,aAAa,KAAK,KAAK,KAAA;EAC/C,mBAAmB,EAAiB,EAAU,iBAAiB;CACjE,IAGK;EACL;EACA,aAAa,EAAiB,EAAY,WAAW;EACrD,mBAAmB,EAAiB,EAAY,iBAAiB;CACnE;AACF"}
1
+ {"version":3,"file":"buildComputeTaskPayload.js","names":[],"sources":["../../../../../../src/features/entity/metadata-task/create-task/utils/buildComputeTaskPayload.ts"],"sourcesContent":["import {\n CurationTask,\n CurationTaskProperties,\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum,\n SampleSheetGenerationExecutionPropertiesConcreteTypeEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { RecordSetFieldsValue } from '../RecordSetFields'\nimport { SampleSheetFieldsValue } from '../SampleSheetFields'\nimport { parseTaskIdInput } from './taskIdValidation'\n\n/** A form's active Compute Data type-specific value, as a discriminated union keyed by `concreteType`. */\nexport type ComputeTypeFields =\n | {\n concreteType: SampleSheetGenerationExecutionPropertiesConcreteTypeEnum\n value: SampleSheetFieldsValue\n }\n | {\n concreteType: RecordSetGenerationExecutionPropertiesConcreteTypeEnum\n value: RecordSetFieldsValue\n }\n\nexport type BuildComputeTaskPayloadArgs = {\n /** The task being edited, if any. Server-managed fields (taskId, etag, etc.) are carried over. */\n existingTask?: CurationTask\n projectId: string\n dataType: string\n instructions: string\n assigneePrincipalId: string | undefined\n /**\n * The Compute Data type-specific fields to write into `taskProperties`. Omit this when editing a task\n * whose category is not one of the two Compute Data types (e.g. a legacy Curate Data task) -- in that\n * case the existing `taskProperties` are carried over unchanged.\n */\n computeTypeFields?: ComputeTypeFields\n}\n\n/**\n * Builds the `CurationTask` payload for creating or updating a Compute Data task from the create/edit\n * task form's field state.\n */\nexport function buildComputeTaskPayload(\n args: BuildComputeTaskPayloadArgs,\n): CurationTask {\n const {\n existingTask,\n projectId,\n dataType,\n instructions,\n assigneePrincipalId,\n computeTypeFields,\n } = args\n\n const taskProperties = computeTypeFields\n ? buildComputeTaskProperties(computeTypeFields)\n : existingTask?.taskProperties\n\n return {\n ...existingTask,\n projectId,\n dataType: dataType.trim() || undefined,\n instructions: instructions.trim() || undefined,\n assigneePrincipalId: assigneePrincipalId || undefined,\n taskProperties,\n }\n}\n\nfunction buildComputeTaskProperties(\n fields: ComputeTypeFields,\n): CurationTaskProperties {\n if (\n fields.concreteType ===\n RecordSetGenerationExecutionPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_execution_RecordSetGenerationExecutionProperties\n ) {\n const { concreteType, value } = fields\n return {\n concreteType,\n folderId: value.folderId.trim() || undefined,\n instructions: value.instructions.trim() || undefined,\n destinationTaskId: parseTaskIdInput(value.destinationTaskId),\n }\n }\n\n const { concreteType, value } = fields\n return {\n concreteType,\n inputTaskId: parseTaskIdInput(value.inputTaskId),\n destinationTaskId: parseTaskIdInput(value.destinationTaskId),\n }\n}\n"],"mappings":";;;AAwCA,SAAgB,EACd,GACc;CACd,IAAM,EACJ,iBACA,cACA,aACA,iBACA,wBACA,yBACE,GAEE,IAAiB,IACnB,EAA2B,CAAiB,IAC5C,GAAc;CAElB,OAAO;EACL,GAAG;EACH;EACA,UAAU,EAAS,KAAK,KAAK,KAAA;EAC7B,cAAc,EAAa,KAAK,KAAK,KAAA;EACrC,qBAAqB,KAAuB,KAAA;EAC5C;CACF;AACF;AAEA,SAAS,EACP,GACwB;CACxB,IACE,EAAO,iBACP,EAAuD,0FACvD;EACA,IAAM,EAAE,iBAAc,aAAU;EAChC,OAAO;GACL;GACA,UAAU,EAAM,SAAS,KAAK,KAAK,KAAA;GACnC,cAAc,EAAM,aAAa,KAAK,KAAK,KAAA;GAC3C,mBAAmB,EAAiB,EAAM,iBAAiB;EAC7D;CACF;CAEA,IAAM,EAAE,iBAAc,aAAU;CAChC,OAAO;EACL;EACA,aAAa,EAAiB,EAAM,WAAW;EAC/C,mBAAmB,EAAiB,EAAM,iBAAiB;CAC7D;AACF"}