create-bluecopa-react-app 1.0.20 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/create-bluecopa-react-app.js +6 -7
- package/package.json +1 -1
- package/templates/latest/app/components/app-sidebar.tsx +5 -0
- package/templates/latest/app/routes/apitest.tsx +1083 -0
- package/templates/latest/app/routes/comments.tsx +335 -60
- package/templates/latest/app/routes.tsx +2 -0
- package/templates/latest/dist/assets/{__federation_expose_App-CcOhEUCE.js → __federation_expose_App-rkiN5ftu.js} +1 -1
- package/templates/latest/dist/assets/{client-uh-HfYnI.js → client-CjZD2orr.js} +5762 -4345
- package/templates/latest/dist/assets/{index-C1IOBHtM.js → index-BIZxzud9.js} +1 -1
- package/templates/latest/dist/assets/remoteEntry.css +130 -0
- package/templates/latest/dist/assets/remoteEntry.js +1 -1
- package/templates/latest/dist/index.html +2 -2
- package/templates/latest/package-lock.json +82 -8
- package/templates/latest/package.json +2 -1
|
@@ -0,0 +1,1083 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { AppSidebar } from "~/components/app-sidebar";
|
|
3
|
+
import { SiteHeader } from "~/components/site-header";
|
|
4
|
+
import { SidebarInset, SidebarProvider } from "~/components/ui/sidebar";
|
|
5
|
+
import {
|
|
6
|
+
Card,
|
|
7
|
+
CardContent,
|
|
8
|
+
CardDescription,
|
|
9
|
+
CardHeader,
|
|
10
|
+
CardTitle,
|
|
11
|
+
} from "~/components/ui/card";
|
|
12
|
+
import { Button } from "~/components/ui/button";
|
|
13
|
+
import { Input } from "~/components/ui/input";
|
|
14
|
+
import { Label } from "~/components/ui/label";
|
|
15
|
+
import { toast } from "sonner";
|
|
16
|
+
import {
|
|
17
|
+
useGetWorkbookDetails,
|
|
18
|
+
useSaveWorkbook,
|
|
19
|
+
usePublishWorkbook,
|
|
20
|
+
useGetTaskDetails,
|
|
21
|
+
useRunRecon,
|
|
22
|
+
useFileUpload,
|
|
23
|
+
useFileDownload,
|
|
24
|
+
useGetFormSchema,
|
|
25
|
+
useGetFormData,
|
|
26
|
+
} from "@bluecopa/react";
|
|
27
|
+
|
|
28
|
+
// Default values for examples
|
|
29
|
+
const DEFAULT_WORKBOOK_ID = "MJ2T21GQ8O8DQXIOHZBF";
|
|
30
|
+
const DEFAULT_TASK_ID = "0V4Kxc7LhIpUvwZeORaj";
|
|
31
|
+
const DEFAULT_WORKFLOW_ID = "MJ02HD1HUJ4VCN66U0V0";
|
|
32
|
+
const DEFAULT_FORM_INSTANCE_ID = "0V5W3KVAWdRnVOZczmSN";
|
|
33
|
+
const DEFAULT_FORM_REVISION = 21949795;
|
|
34
|
+
const DEFAULT_FORM_ID = "";
|
|
35
|
+
const DEFAULT_FILE_UPLOAD_PAYLOAD = {
|
|
36
|
+
id: "0URYQ4DIHB1mVzPA87ZW",
|
|
37
|
+
name: "octobereighteennnqq",
|
|
38
|
+
description: "",
|
|
39
|
+
sequence: [
|
|
40
|
+
{
|
|
41
|
+
step_id: "0URYQFlVMr1DuDagpmlS",
|
|
42
|
+
name: "activity_1_",
|
|
43
|
+
type: "UPDATE_AND_RUN_RECON",
|
|
44
|
+
description: "",
|
|
45
|
+
inputs: {
|
|
46
|
+
recon_run_config_id: "${0URYQEEuxOPKIlGouLr2.form_data.recon_form}",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Workbook Test Component
|
|
53
|
+
function WorkbookTestSection() {
|
|
54
|
+
const [workbookId, setWorkbookId] = useState<string>("");
|
|
55
|
+
const [workbookData, setWorkbookData] = useState<any>(null);
|
|
56
|
+
|
|
57
|
+
// Save Workbook inputs
|
|
58
|
+
const [saveWorkbookData, setSaveWorkbookData] = useState<string>("");
|
|
59
|
+
const [sheetInputs, setSheetInputs] = useState<string>("[]");
|
|
60
|
+
|
|
61
|
+
// Publish Workbook input
|
|
62
|
+
const [publishWorkbookId, setPublishWorkbookId] = useState<string>("");
|
|
63
|
+
|
|
64
|
+
// Get Workbook Details Hook - disabled by default, only runs on user action
|
|
65
|
+
const workbookDetailsQuery = useGetWorkbookDetails(workbookId || null, {
|
|
66
|
+
enabled: false, // No automatic fetching - all calls are user-initiated
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Save Workbook Hook
|
|
70
|
+
const saveWorkbookMutation = useSaveWorkbook();
|
|
71
|
+
|
|
72
|
+
// Publish Workbook Hook
|
|
73
|
+
const publishWorkbookMutation = usePublishWorkbook();
|
|
74
|
+
|
|
75
|
+
// Handle Load Example for Get Workbook
|
|
76
|
+
const handleLoadExample = () => {
|
|
77
|
+
setWorkbookId(DEFAULT_WORKBOOK_ID);
|
|
78
|
+
toast.info(
|
|
79
|
+
'Example workbook ID loaded. Click "Get Workbook Details" to fetch.'
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Handle Load Example for Save Workbook
|
|
84
|
+
const handleLoadSaveExample = () => {
|
|
85
|
+
// Create a minimal example workbook structure
|
|
86
|
+
const exampleWorkbook = {
|
|
87
|
+
name: "sap_test1",
|
|
88
|
+
description: null,
|
|
89
|
+
parentId: null,
|
|
90
|
+
type: "PROCESS",
|
|
91
|
+
addToHome: false,
|
|
92
|
+
path: "prod/MJ2T21GQ8O8DQXIOHZBF",
|
|
93
|
+
sheetIds: ["MJ2T1S6CAWSVEHR5136Z"],
|
|
94
|
+
sheetRevisionById: {
|
|
95
|
+
MJ2T1S6CAWSVEHR5136Z: 21944090,
|
|
96
|
+
},
|
|
97
|
+
published: false,
|
|
98
|
+
sheets: [
|
|
99
|
+
{
|
|
100
|
+
name: "Process",
|
|
101
|
+
sources: null,
|
|
102
|
+
parentId: "MJ2T21GQ8O8DQXIOHZBF",
|
|
103
|
+
parentVersion: null,
|
|
104
|
+
parentType: "PROCESS",
|
|
105
|
+
type: "PROCESS_SHEET",
|
|
106
|
+
published: false,
|
|
107
|
+
customFields: {},
|
|
108
|
+
publishedVersion: null,
|
|
109
|
+
externalUrl:
|
|
110
|
+
"gs://gcp-dev-v3-stage-out/PROC_DEFINITION/MJ6WV5IW2FT808T2JWFK.json",
|
|
111
|
+
modelUrl:
|
|
112
|
+
"gs://gcp-dev-v3-stage-out/PROC_CUSTOM_MODEL/MJ6WV5IYWOZI9YY6M3UR.json",
|
|
113
|
+
tags: null,
|
|
114
|
+
createdBy: "0TOlmUqx0TKseTn8W6gW",
|
|
115
|
+
createdDate: "2025-12-12T11:50:09.155+00:00",
|
|
116
|
+
lastModifiedBy: "0TOlmUqx0TKseTn8W6gW",
|
|
117
|
+
lastModifiedDate: "2025-12-15T08:47:53.402+00:00",
|
|
118
|
+
id: "MJ2T1S6CAWSVEHR5136Z",
|
|
119
|
+
workspaceId: "prod",
|
|
120
|
+
entityVersion: 13,
|
|
121
|
+
definitionFileId: "PROC_DEFINITION/MJ6WV5IW2FT808T2JWFK.json",
|
|
122
|
+
modelFileId: "PROC_CUSTOM_MODEL/MJ6WV5IYWOZI9YY6M3UR.json",
|
|
123
|
+
externalDataId: "PROC_DEFINITION/MJ6WV5IW2FT808T2JWFK.json",
|
|
124
|
+
modelId: "PROC_CUSTOM_MODEL/MJ6WV5IYWOZI9YY6M3UR.json",
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
customFields: {
|
|
128
|
+
formTriggered: {
|
|
129
|
+
value: false,
|
|
130
|
+
},
|
|
131
|
+
httpTriggered: {
|
|
132
|
+
value: false,
|
|
133
|
+
},
|
|
134
|
+
manualTriggered: {
|
|
135
|
+
value: true,
|
|
136
|
+
},
|
|
137
|
+
scheduledTriggered: {
|
|
138
|
+
value: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
indexedForAssistant: false,
|
|
142
|
+
tags: null,
|
|
143
|
+
builderSpaceType: null,
|
|
144
|
+
latestVersionPublished: true,
|
|
145
|
+
createdBy: "0TOlmUqx0TKseTn8W6gW",
|
|
146
|
+
createdDate: "2025-12-12T11:50:09.183+00:00",
|
|
147
|
+
lastModifiedBy: "0TOlmUqx0TKseTn8W6gW",
|
|
148
|
+
lastModifiedDate: "2025-12-16T05:35:08.035+00:00",
|
|
149
|
+
id: "MJ2T21GQ8O8DQXIOHZBF",
|
|
150
|
+
workspaceId: "prod",
|
|
151
|
+
entityVersion: 9,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
setSaveWorkbookData(JSON.stringify(exampleWorkbook, null, 2));
|
|
155
|
+
setSheetInputs("[]");
|
|
156
|
+
toast.info('Example workbook data loaded. Click "Save Workbook" to save.');
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Handle Load Example for Publish Workbook
|
|
160
|
+
const handleLoadPublishExample = () => {
|
|
161
|
+
setPublishWorkbookId(DEFAULT_WORKBOOK_ID);
|
|
162
|
+
toast.info(
|
|
163
|
+
'Example workbook ID loaded. Click "Publish Workbook" to publish.'
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Handle Get Workbook Details
|
|
168
|
+
const handleGetWorkbookDetails = async () => {
|
|
169
|
+
if (!workbookId) {
|
|
170
|
+
toast.error("Please enter a workbook ID");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const result = await workbookDetailsQuery.refetch();
|
|
175
|
+
if (result.data) {
|
|
176
|
+
setWorkbookData(result.data);
|
|
177
|
+
console.log("Workbook details:", result.data);
|
|
178
|
+
toast.success("Workbook details loaded! Check console for data.");
|
|
179
|
+
}
|
|
180
|
+
} catch (error: any) {
|
|
181
|
+
toast.error(`Error: ${error.message}`);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Handle Save Workbook
|
|
186
|
+
const handleSaveWorkbook = async () => {
|
|
187
|
+
if (!saveWorkbookData) {
|
|
188
|
+
toast.error("Please enter workbook data (JSON)");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
let parsedWorkbook;
|
|
193
|
+
let parsedSheetInputs;
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
parsedWorkbook = JSON.parse(saveWorkbookData);
|
|
197
|
+
} catch (e) {
|
|
198
|
+
toast.error("Invalid JSON format for workbook data");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
parsedSheetInputs = JSON.parse(sheetInputs);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
toast.error("Invalid JSON format for sheet inputs");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const result = await saveWorkbookMutation.mutateAsync({
|
|
210
|
+
workbook: parsedWorkbook,
|
|
211
|
+
sheetInputs: parsedSheetInputs,
|
|
212
|
+
});
|
|
213
|
+
console.log("Workbook saved:", result);
|
|
214
|
+
toast.success("Workbook saved successfully! Check console for data.");
|
|
215
|
+
} catch (error: any) {
|
|
216
|
+
console.error("Save error:", error);
|
|
217
|
+
toast.error(`Save failed: ${error.message}`);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Handle Publish Workbook
|
|
222
|
+
const handlePublishWorkbook = async () => {
|
|
223
|
+
if (!publishWorkbookId) {
|
|
224
|
+
toast.error("Please enter a workbook ID");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const result = await publishWorkbookMutation.mutateAsync({
|
|
229
|
+
workbookId: publishWorkbookId,
|
|
230
|
+
});
|
|
231
|
+
console.log("Workbook published:", result);
|
|
232
|
+
toast.success("Workbook published successfully! Check console for data.");
|
|
233
|
+
} catch (error: any) {
|
|
234
|
+
console.error("Publish error:", error);
|
|
235
|
+
toast.error(`Publish failed: ${error.message}`);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
<Card className="mb-6">
|
|
241
|
+
<CardHeader>
|
|
242
|
+
<CardTitle>Workbook Operations Test</CardTitle>
|
|
243
|
+
<CardDescription>
|
|
244
|
+
Get, save, and publish workbook details
|
|
245
|
+
</CardDescription>
|
|
246
|
+
</CardHeader>
|
|
247
|
+
<CardContent className="space-y-4">
|
|
248
|
+
<div className="space-y-2">
|
|
249
|
+
<Label htmlFor="workbookId">Workbook ID</Label>
|
|
250
|
+
<div className="flex gap-2">
|
|
251
|
+
<Input
|
|
252
|
+
id="workbookId"
|
|
253
|
+
value={workbookId}
|
|
254
|
+
onChange={(e) => setWorkbookId(e.target.value)}
|
|
255
|
+
placeholder="Enter workbook ID"
|
|
256
|
+
/>
|
|
257
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
258
|
+
Load Example
|
|
259
|
+
</Button>
|
|
260
|
+
</div>
|
|
261
|
+
<p className="text-xs text-muted-foreground">
|
|
262
|
+
Example:{" "}
|
|
263
|
+
<button
|
|
264
|
+
type="button"
|
|
265
|
+
onClick={handleLoadExample}
|
|
266
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
267
|
+
>
|
|
268
|
+
{DEFAULT_WORKBOOK_ID}
|
|
269
|
+
</button>
|
|
270
|
+
</p>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<div className="flex gap-4">
|
|
274
|
+
<Button
|
|
275
|
+
onClick={handleGetWorkbookDetails}
|
|
276
|
+
disabled={workbookDetailsQuery.isLoading || !workbookId}
|
|
277
|
+
variant="default"
|
|
278
|
+
>
|
|
279
|
+
{workbookDetailsQuery.isLoading
|
|
280
|
+
? "Loading..."
|
|
281
|
+
: "1. Get Workbook Details"}
|
|
282
|
+
</Button>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
{/* Status Messages for Get Workbook */}
|
|
286
|
+
{workbookDetailsQuery.isError && (
|
|
287
|
+
<p className="text-red-500">
|
|
288
|
+
Get Error: {workbookDetailsQuery.error?.message}
|
|
289
|
+
</p>
|
|
290
|
+
)}
|
|
291
|
+
{workbookDetailsQuery.isSuccess && workbookData && (
|
|
292
|
+
<p className="text-green-500">
|
|
293
|
+
✓ Workbook details loaded (ID: {workbookData.id})
|
|
294
|
+
</p>
|
|
295
|
+
)}
|
|
296
|
+
|
|
297
|
+
{/* Workbook Data Preview */}
|
|
298
|
+
{workbookData && (
|
|
299
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
300
|
+
<p className="text-sm font-semibold mb-2">Workbook Data:</p>
|
|
301
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
302
|
+
{JSON.stringify(workbookData, null, 2)}
|
|
303
|
+
</pre>
|
|
304
|
+
</div>
|
|
305
|
+
)}
|
|
306
|
+
|
|
307
|
+
{/* Save Workbook Section */}
|
|
308
|
+
<div className="border-t pt-4 mt-4 space-y-4">
|
|
309
|
+
<h3 className="text-lg font-semibold">Save Workbook</h3>
|
|
310
|
+
<div className="space-y-2">
|
|
311
|
+
<Label htmlFor="saveWorkbookData">Workbook Data (JSON)</Label>
|
|
312
|
+
<div className="flex gap-2 mb-2">
|
|
313
|
+
<Button
|
|
314
|
+
onClick={handleLoadSaveExample}
|
|
315
|
+
variant="outline"
|
|
316
|
+
type="button"
|
|
317
|
+
>
|
|
318
|
+
Load Example
|
|
319
|
+
</Button>
|
|
320
|
+
</div>
|
|
321
|
+
<textarea
|
|
322
|
+
id="saveWorkbookData"
|
|
323
|
+
value={saveWorkbookData}
|
|
324
|
+
onChange={(e) => setSaveWorkbookData(e.target.value)}
|
|
325
|
+
placeholder="Enter workbook JSON data"
|
|
326
|
+
className="w-full min-h-[150px] p-2 border rounded-md font-mono text-xs"
|
|
327
|
+
/>
|
|
328
|
+
<p className="text-xs text-muted-foreground">
|
|
329
|
+
Example: Click "Load Example" button above to load sample workbook
|
|
330
|
+
data
|
|
331
|
+
</p>
|
|
332
|
+
</div>
|
|
333
|
+
|
|
334
|
+
<div className="space-y-2">
|
|
335
|
+
<Label htmlFor="sheetInputs">Sheet Inputs (JSON Array)</Label>
|
|
336
|
+
<Input
|
|
337
|
+
id="sheetInputs"
|
|
338
|
+
value={sheetInputs}
|
|
339
|
+
onChange={(e) => setSheetInputs(e.target.value)}
|
|
340
|
+
placeholder="Enter sheet inputs as JSON array, e.g., []"
|
|
341
|
+
className="font-mono text-xs"
|
|
342
|
+
/>
|
|
343
|
+
<p className="text-xs text-muted-foreground">
|
|
344
|
+
Example: <code className="bg-muted px-1 rounded">[]</code> (empty
|
|
345
|
+
array)
|
|
346
|
+
</p>
|
|
347
|
+
</div>
|
|
348
|
+
|
|
349
|
+
<div className="space-y-2">
|
|
350
|
+
<Button
|
|
351
|
+
onClick={handleSaveWorkbook}
|
|
352
|
+
disabled={saveWorkbookMutation.isPending || !saveWorkbookData}
|
|
353
|
+
variant="default"
|
|
354
|
+
>
|
|
355
|
+
{saveWorkbookMutation.isPending ? "Saving..." : "2. Save Workbook"}
|
|
356
|
+
</Button>
|
|
357
|
+
|
|
358
|
+
{/* Status Messages for Save Workbook */}
|
|
359
|
+
{saveWorkbookMutation.isError && (
|
|
360
|
+
<p className="text-red-500">
|
|
361
|
+
Save Error: {saveWorkbookMutation.error?.message}
|
|
362
|
+
</p>
|
|
363
|
+
)}
|
|
364
|
+
{saveWorkbookMutation.isSuccess && (
|
|
365
|
+
<p className="text-green-500">✓ Workbook saved successfully</p>
|
|
366
|
+
)}
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
{/* Publish Workbook Section */}
|
|
371
|
+
<div className="border-t pt-4 mt-4 space-y-4">
|
|
372
|
+
<h3 className="text-lg font-semibold">Publish Workbook</h3>
|
|
373
|
+
<div className="space-y-2">
|
|
374
|
+
<Label htmlFor="publishWorkbookId">Workbook ID</Label>
|
|
375
|
+
<div className="flex gap-2">
|
|
376
|
+
<Input
|
|
377
|
+
id="publishWorkbookId"
|
|
378
|
+
value={publishWorkbookId}
|
|
379
|
+
onChange={(e) => setPublishWorkbookId(e.target.value)}
|
|
380
|
+
placeholder="Enter workbook ID"
|
|
381
|
+
/>
|
|
382
|
+
<Button
|
|
383
|
+
onClick={handleLoadPublishExample}
|
|
384
|
+
variant="outline"
|
|
385
|
+
type="button"
|
|
386
|
+
>
|
|
387
|
+
Load Example
|
|
388
|
+
</Button>
|
|
389
|
+
</div>
|
|
390
|
+
<p className="text-xs text-muted-foreground">
|
|
391
|
+
Example:{" "}
|
|
392
|
+
<button
|
|
393
|
+
type="button"
|
|
394
|
+
onClick={handleLoadPublishExample}
|
|
395
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
396
|
+
>
|
|
397
|
+
{DEFAULT_WORKBOOK_ID}
|
|
398
|
+
</button>
|
|
399
|
+
</p>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
<Button
|
|
403
|
+
onClick={handlePublishWorkbook}
|
|
404
|
+
disabled={publishWorkbookMutation.isPending || !publishWorkbookId}
|
|
405
|
+
variant="default"
|
|
406
|
+
>
|
|
407
|
+
{publishWorkbookMutation.isPending
|
|
408
|
+
? "Publishing..."
|
|
409
|
+
: "3. Publish Workbook"}
|
|
410
|
+
</Button>
|
|
411
|
+
|
|
412
|
+
{/* Status Messages for Publish Workbook */}
|
|
413
|
+
{publishWorkbookMutation.isError && (
|
|
414
|
+
<p className="text-red-500">
|
|
415
|
+
Publish Error: {publishWorkbookMutation.error?.message}
|
|
416
|
+
</p>
|
|
417
|
+
)}
|
|
418
|
+
{publishWorkbookMutation.isSuccess && (
|
|
419
|
+
<p className="text-green-500">✓ Workbook published successfully</p>
|
|
420
|
+
)}
|
|
421
|
+
</div>
|
|
422
|
+
</CardContent>
|
|
423
|
+
</Card>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Task Test Component
|
|
428
|
+
function TaskTestSection() {
|
|
429
|
+
const [taskId, setTaskId] = useState<string>("");
|
|
430
|
+
|
|
431
|
+
// Get Task Details Hook - disabled by default
|
|
432
|
+
const taskDetailsQuery = useGetTaskDetails(taskId || null, {
|
|
433
|
+
enabled: false, // No automatic fetching - all calls are user-initiated
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
// Handle Load Example
|
|
437
|
+
const handleLoadExample = () => {
|
|
438
|
+
setTaskId(DEFAULT_TASK_ID);
|
|
439
|
+
toast.info('Example task ID loaded. Click "Get Task Details" to fetch.');
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// Handle Get Task Details
|
|
443
|
+
const handleGetTaskDetails = async () => {
|
|
444
|
+
if (!taskId) {
|
|
445
|
+
toast.error("Please enter a task ID");
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
const result = await taskDetailsQuery.refetch();
|
|
450
|
+
if (result.data) {
|
|
451
|
+
console.log("Task details:", result.data);
|
|
452
|
+
toast.success("Task details loaded! Check console for data.");
|
|
453
|
+
}
|
|
454
|
+
} catch (error: any) {
|
|
455
|
+
toast.error(`Error: ${error.message}`);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
return (
|
|
460
|
+
<Card className="mb-6">
|
|
461
|
+
<CardHeader>
|
|
462
|
+
<CardTitle>Task Operations Test</CardTitle>
|
|
463
|
+
<CardDescription>Get task details by task ID</CardDescription>
|
|
464
|
+
</CardHeader>
|
|
465
|
+
<CardContent className="space-y-4">
|
|
466
|
+
<div className="space-y-2">
|
|
467
|
+
<Label htmlFor="taskId">Task ID</Label>
|
|
468
|
+
<div className="flex gap-2">
|
|
469
|
+
<Input
|
|
470
|
+
id="taskId"
|
|
471
|
+
value={taskId}
|
|
472
|
+
onChange={(e) => setTaskId(e.target.value)}
|
|
473
|
+
placeholder="Enter task ID"
|
|
474
|
+
/>
|
|
475
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
476
|
+
Load Example
|
|
477
|
+
</Button>
|
|
478
|
+
</div>
|
|
479
|
+
<p className="text-xs text-muted-foreground">
|
|
480
|
+
Example:{" "}
|
|
481
|
+
<button
|
|
482
|
+
type="button"
|
|
483
|
+
onClick={handleLoadExample}
|
|
484
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
485
|
+
>
|
|
486
|
+
{DEFAULT_TASK_ID}
|
|
487
|
+
</button>
|
|
488
|
+
</p>
|
|
489
|
+
</div>
|
|
490
|
+
|
|
491
|
+
<div className="flex gap-4">
|
|
492
|
+
<Button
|
|
493
|
+
onClick={handleGetTaskDetails}
|
|
494
|
+
disabled={taskDetailsQuery.isLoading || !taskId}
|
|
495
|
+
variant="default"
|
|
496
|
+
>
|
|
497
|
+
{taskDetailsQuery.isLoading ? "Loading..." : "Get Task Details"}
|
|
498
|
+
</Button>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
{/* Status Messages */}
|
|
502
|
+
{taskDetailsQuery.isError && (
|
|
503
|
+
<p className="text-red-500">
|
|
504
|
+
Get Error: {taskDetailsQuery.error?.message}
|
|
505
|
+
</p>
|
|
506
|
+
)}
|
|
507
|
+
{taskDetailsQuery.isSuccess && taskDetailsQuery.data && (
|
|
508
|
+
<p className="text-green-500">
|
|
509
|
+
✓ Task details loaded (ID: {taskDetailsQuery.data.id || taskId})
|
|
510
|
+
</p>
|
|
511
|
+
)}
|
|
512
|
+
|
|
513
|
+
{/* Task Data Preview */}
|
|
514
|
+
{taskDetailsQuery.data && (
|
|
515
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
516
|
+
<p className="text-sm font-semibold mb-2">Task Data:</p>
|
|
517
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
518
|
+
{JSON.stringify(taskDetailsQuery.data, null, 2)}
|
|
519
|
+
</pre>
|
|
520
|
+
</div>
|
|
521
|
+
)}
|
|
522
|
+
</CardContent>
|
|
523
|
+
</Card>
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Run Recon Test Component
|
|
528
|
+
function RunReconTestSection() {
|
|
529
|
+
const [workflowId, setWorkflowId] = useState<string>("");
|
|
530
|
+
const [fullRefresh, setFullRefresh] = useState<boolean>(true);
|
|
531
|
+
const [reconResult, setReconResult] = useState<any>(null);
|
|
532
|
+
|
|
533
|
+
// Run Recon Hook
|
|
534
|
+
const runReconMutation = useRunRecon();
|
|
535
|
+
|
|
536
|
+
// Handle Load Example
|
|
537
|
+
const handleLoadExample = () => {
|
|
538
|
+
setWorkflowId(DEFAULT_WORKFLOW_ID);
|
|
539
|
+
setFullRefresh(true);
|
|
540
|
+
toast.info('Example workflow ID loaded. Click "Run Recon" to execute.');
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// Handle Run Recon
|
|
544
|
+
const handleRunRecon = async () => {
|
|
545
|
+
if (!workflowId) {
|
|
546
|
+
toast.error("Please enter a workflow ID");
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
try {
|
|
550
|
+
const result = await runReconMutation.mutateAsync({
|
|
551
|
+
workflowId: workflowId,
|
|
552
|
+
fullRefresh: fullRefresh,
|
|
553
|
+
});
|
|
554
|
+
console.log("Run Recon result:", result);
|
|
555
|
+
setReconResult(result);
|
|
556
|
+
toast.success("Recon workflow started! Check console for data.");
|
|
557
|
+
} catch (error: any) {
|
|
558
|
+
console.error("Run Recon error:", error);
|
|
559
|
+
toast.error(`Run Recon failed: ${error.message}`);
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
return (
|
|
564
|
+
<Card className="mb-6">
|
|
565
|
+
<CardHeader>
|
|
566
|
+
<CardTitle>Run Recon Operations Test</CardTitle>
|
|
567
|
+
<CardDescription>Run a reconciliation workflow</CardDescription>
|
|
568
|
+
</CardHeader>
|
|
569
|
+
<CardContent className="space-y-4">
|
|
570
|
+
<div className="space-y-2">
|
|
571
|
+
<Label htmlFor="workflowId">Workflow ID</Label>
|
|
572
|
+
<div className="flex gap-2">
|
|
573
|
+
<Input
|
|
574
|
+
id="workflowId"
|
|
575
|
+
value={workflowId}
|
|
576
|
+
onChange={(e) => setWorkflowId(e.target.value)}
|
|
577
|
+
placeholder="Enter workflow ID"
|
|
578
|
+
/>
|
|
579
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
580
|
+
Load Example
|
|
581
|
+
</Button>
|
|
582
|
+
</div>
|
|
583
|
+
<p className="text-xs text-muted-foreground">
|
|
584
|
+
Example:{" "}
|
|
585
|
+
<button
|
|
586
|
+
type="button"
|
|
587
|
+
onClick={handleLoadExample}
|
|
588
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
589
|
+
>
|
|
590
|
+
{DEFAULT_WORKFLOW_ID}
|
|
591
|
+
</button>
|
|
592
|
+
</p>
|
|
593
|
+
</div>
|
|
594
|
+
|
|
595
|
+
<div className="flex items-center gap-2">
|
|
596
|
+
<input
|
|
597
|
+
type="checkbox"
|
|
598
|
+
id="fullRefresh"
|
|
599
|
+
checked={fullRefresh}
|
|
600
|
+
onChange={(e) => setFullRefresh(e.target.checked)}
|
|
601
|
+
className="h-4 w-4"
|
|
602
|
+
/>
|
|
603
|
+
<Label htmlFor="fullRefresh" className="cursor-pointer">
|
|
604
|
+
Full Refresh
|
|
605
|
+
</Label>
|
|
606
|
+
</div>
|
|
607
|
+
|
|
608
|
+
<div className="flex gap-4">
|
|
609
|
+
<Button
|
|
610
|
+
onClick={handleRunRecon}
|
|
611
|
+
disabled={runReconMutation.isPending || !workflowId}
|
|
612
|
+
variant="default"
|
|
613
|
+
>
|
|
614
|
+
{runReconMutation.isPending ? "Running..." : "Run Recon"}
|
|
615
|
+
</Button>
|
|
616
|
+
</div>
|
|
617
|
+
|
|
618
|
+
{/* Status Messages */}
|
|
619
|
+
{runReconMutation.isError && (
|
|
620
|
+
<p className="text-red-500">
|
|
621
|
+
Run Recon Error: {runReconMutation.error?.message}
|
|
622
|
+
</p>
|
|
623
|
+
)}
|
|
624
|
+
{runReconMutation.isSuccess && reconResult && (
|
|
625
|
+
<p className="text-green-500">
|
|
626
|
+
✓ Recon workflow started successfully
|
|
627
|
+
</p>
|
|
628
|
+
)}
|
|
629
|
+
|
|
630
|
+
{/* Recon Result Preview */}
|
|
631
|
+
{reconResult && (
|
|
632
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
633
|
+
<p className="text-sm font-semibold mb-2">Recon Result:</p>
|
|
634
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
635
|
+
{JSON.stringify(reconResult, null, 2)}
|
|
636
|
+
</pre>
|
|
637
|
+
</div>
|
|
638
|
+
)}
|
|
639
|
+
</CardContent>
|
|
640
|
+
</Card>
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// File Upload Test Component
|
|
645
|
+
function FileUploadTestSection() {
|
|
646
|
+
const [fileUploadData, setFileUploadData] = useState<string>("");
|
|
647
|
+
const [fileId, setFileId] = useState<string>("");
|
|
648
|
+
const [downloadedData, setDownloadedData] = useState<any>(null);
|
|
649
|
+
|
|
650
|
+
// File Upload Hook
|
|
651
|
+
const fileUploadMutation = useFileUpload();
|
|
652
|
+
|
|
653
|
+
// File Download Hook - disabled by default
|
|
654
|
+
const fileDownloadQuery = useFileDownload(fileId || null, {
|
|
655
|
+
enabled: false, // No automatic fetching - all calls are user-initiated
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
// Handle Load Example
|
|
659
|
+
const handleLoadExample = () => {
|
|
660
|
+
setFileUploadData(JSON.stringify(DEFAULT_FILE_UPLOAD_PAYLOAD, null, 2));
|
|
661
|
+
toast.info('Example payload loaded. Click "Upload File" to upload.');
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
// Handle File Upload
|
|
665
|
+
const handleFileUpload = async () => {
|
|
666
|
+
if (!fileUploadData) {
|
|
667
|
+
toast.error("Please enter file data (JSON)");
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
try {
|
|
671
|
+
let parsedData;
|
|
672
|
+
try {
|
|
673
|
+
parsedData = JSON.parse(fileUploadData);
|
|
674
|
+
} catch (e) {
|
|
675
|
+
toast.error("Invalid JSON format");
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const result = await fileUploadMutation.mutateAsync({
|
|
680
|
+
data: parsedData,
|
|
681
|
+
uploadType: "DEFINITION",
|
|
682
|
+
});
|
|
683
|
+
console.log("File uploaded, fileId:", result.fileId);
|
|
684
|
+
setFileId(result.fileId);
|
|
685
|
+
toast.success(`File uploaded successfully! File ID: ${result.fileId}`);
|
|
686
|
+
} catch (error: any) {
|
|
687
|
+
console.error("File upload error:", error);
|
|
688
|
+
toast.error(`File upload failed: ${error.message}`);
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// Handle File Download
|
|
693
|
+
const handleFileDownload = async () => {
|
|
694
|
+
if (!fileId) {
|
|
695
|
+
toast.error("Please upload a file first to get fileId");
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
try {
|
|
699
|
+
const result = await fileDownloadQuery.refetch();
|
|
700
|
+
if (result.data) {
|
|
701
|
+
setDownloadedData(result.data);
|
|
702
|
+
console.log("File downloaded:", result.data);
|
|
703
|
+
toast.success("File downloaded! Check console for data.");
|
|
704
|
+
}
|
|
705
|
+
} catch (error: any) {
|
|
706
|
+
toast.error(`Download Error: ${error.message}`);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
return (
|
|
711
|
+
<Card className="mb-6">
|
|
712
|
+
<CardHeader>
|
|
713
|
+
<CardTitle>File Upload/Download Operations Test</CardTitle>
|
|
714
|
+
<CardDescription>
|
|
715
|
+
Upload a file, get fileId, then download and display the file
|
|
716
|
+
</CardDescription>
|
|
717
|
+
</CardHeader>
|
|
718
|
+
<CardContent className="space-y-4">
|
|
719
|
+
<div className="space-y-2">
|
|
720
|
+
<Label htmlFor="fileUploadData">File Data (JSON)</Label>
|
|
721
|
+
<div className="flex gap-2 mb-2">
|
|
722
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
723
|
+
Load Example
|
|
724
|
+
</Button>
|
|
725
|
+
</div>
|
|
726
|
+
<textarea
|
|
727
|
+
id="fileUploadData"
|
|
728
|
+
value={fileUploadData}
|
|
729
|
+
onChange={(e) => setFileUploadData(e.target.value)}
|
|
730
|
+
placeholder="Enter JSON data to upload"
|
|
731
|
+
className="w-full min-h-[150px] p-2 border rounded-md font-mono text-xs"
|
|
732
|
+
/>
|
|
733
|
+
<p className="text-xs text-muted-foreground">
|
|
734
|
+
Example: Click "Load Example" button above to load sample JSON
|
|
735
|
+
payload
|
|
736
|
+
</p>
|
|
737
|
+
</div>
|
|
738
|
+
|
|
739
|
+
<div className="space-y-2">
|
|
740
|
+
<Label htmlFor="fileId">File ID (from upload response)</Label>
|
|
741
|
+
<Input
|
|
742
|
+
id="fileId"
|
|
743
|
+
value={fileId}
|
|
744
|
+
onChange={(e) => setFileId(e.target.value)}
|
|
745
|
+
placeholder="File ID will appear here after upload"
|
|
746
|
+
/>
|
|
747
|
+
</div>
|
|
748
|
+
|
|
749
|
+
<div className="flex gap-4">
|
|
750
|
+
<Button
|
|
751
|
+
onClick={handleFileUpload}
|
|
752
|
+
disabled={fileUploadMutation.isPending || !fileUploadData}
|
|
753
|
+
variant="default"
|
|
754
|
+
>
|
|
755
|
+
{fileUploadMutation.isPending ? "Uploading..." : "1. Upload File"}
|
|
756
|
+
</Button>
|
|
757
|
+
|
|
758
|
+
<Button
|
|
759
|
+
onClick={handleFileDownload}
|
|
760
|
+
disabled={fileDownloadQuery.isLoading || !fileId}
|
|
761
|
+
variant="default"
|
|
762
|
+
>
|
|
763
|
+
{fileDownloadQuery.isLoading
|
|
764
|
+
? "Downloading..."
|
|
765
|
+
: "2. Download File"}
|
|
766
|
+
</Button>
|
|
767
|
+
</div>
|
|
768
|
+
|
|
769
|
+
{/* Status Messages */}
|
|
770
|
+
{fileUploadMutation.isError && (
|
|
771
|
+
<p className="text-red-500">
|
|
772
|
+
Upload Error: {fileUploadMutation.error?.message}
|
|
773
|
+
</p>
|
|
774
|
+
)}
|
|
775
|
+
{fileUploadMutation.isSuccess && fileId && (
|
|
776
|
+
<p className="text-green-500">
|
|
777
|
+
✓ File uploaded successfully (File ID: {fileId})
|
|
778
|
+
</p>
|
|
779
|
+
)}
|
|
780
|
+
|
|
781
|
+
{fileDownloadQuery.isError && (
|
|
782
|
+
<p className="text-red-500">
|
|
783
|
+
Download Error: {fileDownloadQuery.error?.message}
|
|
784
|
+
</p>
|
|
785
|
+
)}
|
|
786
|
+
{fileDownloadQuery.isSuccess && downloadedData && (
|
|
787
|
+
<p className="text-green-500">✓ File downloaded successfully</p>
|
|
788
|
+
)}
|
|
789
|
+
|
|
790
|
+
{/* Uploaded Payload Preview */}
|
|
791
|
+
{fileUploadMutation.isSuccess && fileUploadData && (
|
|
792
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
793
|
+
<p className="text-sm font-semibold mb-2">Uploaded Payload:</p>
|
|
794
|
+
<pre className="text-xs overflow-auto max-h-40">
|
|
795
|
+
{fileUploadData}
|
|
796
|
+
</pre>
|
|
797
|
+
</div>
|
|
798
|
+
)}
|
|
799
|
+
|
|
800
|
+
{/* Downloaded File Data Preview */}
|
|
801
|
+
{downloadedData && (
|
|
802
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
803
|
+
<p className="text-sm font-semibold mb-2">Downloaded File Data:</p>
|
|
804
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
805
|
+
{JSON.stringify(downloadedData, null, 2)}
|
|
806
|
+
</pre>
|
|
807
|
+
</div>
|
|
808
|
+
)}
|
|
809
|
+
</CardContent>
|
|
810
|
+
</Card>
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Form Schema Test Component
|
|
815
|
+
function FormSchemaTestSection() {
|
|
816
|
+
const [formInstanceId, setFormInstanceId] = useState<string>("");
|
|
817
|
+
const [formRevision, setFormRevision] = useState<number>(1);
|
|
818
|
+
|
|
819
|
+
// Get Form Schema Hook - disabled by default
|
|
820
|
+
const formSchemaQuery = useGetFormSchema(
|
|
821
|
+
formInstanceId || null,
|
|
822
|
+
formRevision ? Number(formRevision) : null
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
// Handle Load Example
|
|
826
|
+
const handleLoadExample = () => {
|
|
827
|
+
setFormInstanceId(DEFAULT_FORM_INSTANCE_ID);
|
|
828
|
+
setFormRevision(DEFAULT_FORM_REVISION);
|
|
829
|
+
toast.info(
|
|
830
|
+
'Example form instance ID and revision loaded. Click "Get Form Schema" to fetch.'
|
|
831
|
+
);
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
// Handle Get Form Schema
|
|
835
|
+
const handleGetFormSchema = async () => {
|
|
836
|
+
if (!formInstanceId || !formRevision) {
|
|
837
|
+
toast.error("Please enter form instance ID and revision");
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
try {
|
|
841
|
+
const result = await formSchemaQuery.refetch();
|
|
842
|
+
if (result.data) {
|
|
843
|
+
console.log("Form schema:", result.data);
|
|
844
|
+
toast.success("Form schema loaded! Check console for data.");
|
|
845
|
+
}
|
|
846
|
+
} catch (error: any) {
|
|
847
|
+
toast.error(`Error: ${error.message}`);
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
return (
|
|
852
|
+
<Card className="mb-6">
|
|
853
|
+
<CardHeader>
|
|
854
|
+
<CardTitle>Form Schema Operations Test</CardTitle>
|
|
855
|
+
<CardDescription>Get form schema by form instance ID and revision</CardDescription>
|
|
856
|
+
</CardHeader>
|
|
857
|
+
<CardContent className="space-y-4">
|
|
858
|
+
<div className="space-y-2">
|
|
859
|
+
<Label htmlFor="formInstanceId">Form Instance ID</Label>
|
|
860
|
+
<div className="flex gap-2">
|
|
861
|
+
<Input
|
|
862
|
+
id="formInstanceId"
|
|
863
|
+
value={formInstanceId}
|
|
864
|
+
onChange={(e) => setFormInstanceId(e.target.value)}
|
|
865
|
+
placeholder="Enter form instance ID"
|
|
866
|
+
/>
|
|
867
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
868
|
+
Load Example
|
|
869
|
+
</Button>
|
|
870
|
+
</div>
|
|
871
|
+
<p className="text-xs text-muted-foreground">
|
|
872
|
+
Example:{" "}
|
|
873
|
+
<button
|
|
874
|
+
type="button"
|
|
875
|
+
onClick={handleLoadExample}
|
|
876
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
877
|
+
>
|
|
878
|
+
{DEFAULT_FORM_INSTANCE_ID || "Enter form instance ID"}
|
|
879
|
+
</button>
|
|
880
|
+
</p>
|
|
881
|
+
</div>
|
|
882
|
+
|
|
883
|
+
<div className="space-y-2">
|
|
884
|
+
<Label htmlFor="formRevision">Form Revision</Label>
|
|
885
|
+
<Input
|
|
886
|
+
id="formRevision"
|
|
887
|
+
value={formRevision}
|
|
888
|
+
onChange={(e) => setFormRevision(Number(e.target.value) || 1)}
|
|
889
|
+
placeholder="Enter form revision (e.g., 1)"
|
|
890
|
+
/>
|
|
891
|
+
<p className="text-xs text-muted-foreground">
|
|
892
|
+
Example: <code className="bg-muted px-1 rounded">{DEFAULT_FORM_REVISION}</code>
|
|
893
|
+
</p>
|
|
894
|
+
</div>
|
|
895
|
+
|
|
896
|
+
<div className="flex gap-4">
|
|
897
|
+
<Button
|
|
898
|
+
onClick={handleGetFormSchema}
|
|
899
|
+
disabled={formSchemaQuery.isLoading || !formInstanceId || !formRevision}
|
|
900
|
+
variant="default"
|
|
901
|
+
>
|
|
902
|
+
{formSchemaQuery.isLoading ? "Loading..." : "Get Form Schema"}
|
|
903
|
+
</Button>
|
|
904
|
+
</div>
|
|
905
|
+
|
|
906
|
+
{/* Status Messages */}
|
|
907
|
+
{formSchemaQuery.isError && (
|
|
908
|
+
<p className="text-red-500">
|
|
909
|
+
Get Error: {formSchemaQuery.error?.message}
|
|
910
|
+
</p>
|
|
911
|
+
)}
|
|
912
|
+
{formSchemaQuery.isSuccess && formSchemaQuery.data && (
|
|
913
|
+
<p className="text-green-500">
|
|
914
|
+
✓ Form schema loaded successfully
|
|
915
|
+
</p>
|
|
916
|
+
)}
|
|
917
|
+
|
|
918
|
+
{/* Form Schema Data Preview */}
|
|
919
|
+
{formSchemaQuery.data && (
|
|
920
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
921
|
+
<p className="text-sm font-semibold mb-2">Form Schema Data:</p>
|
|
922
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
923
|
+
{JSON.stringify(formSchemaQuery.data, null, 2)}
|
|
924
|
+
</pre>
|
|
925
|
+
</div>
|
|
926
|
+
)}
|
|
927
|
+
</CardContent>
|
|
928
|
+
</Card>
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Form Data Test Component
|
|
933
|
+
function FormDataTestSection() {
|
|
934
|
+
const [formId, setFormId] = useState<string>("");
|
|
935
|
+
|
|
936
|
+
// Get Form Data Hook - disabled by default
|
|
937
|
+
const formDataQuery = useGetFormData(formId || null);
|
|
938
|
+
|
|
939
|
+
// Handle Load Example
|
|
940
|
+
const handleLoadExample = () => {
|
|
941
|
+
setFormId(DEFAULT_FORM_ID);
|
|
942
|
+
toast.info(
|
|
943
|
+
'Example form ID loaded. Click "Get Form Data" to fetch.'
|
|
944
|
+
);
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
// Handle Get Form Data
|
|
948
|
+
const handleGetFormData = async () => {
|
|
949
|
+
if (!formId) {
|
|
950
|
+
toast.error("Please enter a form ID");
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
try {
|
|
954
|
+
const result = await formDataQuery.refetch();
|
|
955
|
+
if (result.data) {
|
|
956
|
+
console.log("Form data:", result.data);
|
|
957
|
+
toast.success("Form data loaded! Check console for data.");
|
|
958
|
+
}
|
|
959
|
+
} catch (error: any) {
|
|
960
|
+
toast.error(`Error: ${error.message}`);
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
return (
|
|
965
|
+
<Card className="mb-6">
|
|
966
|
+
<CardHeader>
|
|
967
|
+
<CardTitle>Form Data Operations Test</CardTitle>
|
|
968
|
+
<CardDescription>Get form data by form ID</CardDescription>
|
|
969
|
+
</CardHeader>
|
|
970
|
+
<CardContent className="space-y-4">
|
|
971
|
+
<div className="space-y-2">
|
|
972
|
+
<Label htmlFor="formId">Form ID</Label>
|
|
973
|
+
<div className="flex gap-2">
|
|
974
|
+
<Input
|
|
975
|
+
id="formId"
|
|
976
|
+
value={formId}
|
|
977
|
+
onChange={(e) => setFormId(e.target.value)}
|
|
978
|
+
placeholder="Enter form ID"
|
|
979
|
+
/>
|
|
980
|
+
<Button onClick={handleLoadExample} variant="outline" type="button">
|
|
981
|
+
Load Example
|
|
982
|
+
</Button>
|
|
983
|
+
</div>
|
|
984
|
+
<p className="text-xs text-muted-foreground">
|
|
985
|
+
Example:{" "}
|
|
986
|
+
<button
|
|
987
|
+
type="button"
|
|
988
|
+
onClick={handleLoadExample}
|
|
989
|
+
className="underline text-blue-600 hover:text-blue-800"
|
|
990
|
+
>
|
|
991
|
+
{DEFAULT_FORM_ID || "Enter form ID"}
|
|
992
|
+
</button>
|
|
993
|
+
</p>
|
|
994
|
+
</div>
|
|
995
|
+
|
|
996
|
+
<div className="flex gap-4">
|
|
997
|
+
<Button
|
|
998
|
+
onClick={handleGetFormData}
|
|
999
|
+
disabled={formDataQuery.isLoading || !formId}
|
|
1000
|
+
variant="default"
|
|
1001
|
+
>
|
|
1002
|
+
{formDataQuery.isLoading ? "Loading..." : "Get Form Data"}
|
|
1003
|
+
</Button>
|
|
1004
|
+
</div>
|
|
1005
|
+
|
|
1006
|
+
{/* Status Messages */}
|
|
1007
|
+
{formDataQuery.isError && (
|
|
1008
|
+
<p className="text-red-500">
|
|
1009
|
+
Get Error: {formDataQuery.error?.message}
|
|
1010
|
+
</p>
|
|
1011
|
+
)}
|
|
1012
|
+
{formDataQuery.isSuccess && formDataQuery.data && (
|
|
1013
|
+
<p className="text-green-500">
|
|
1014
|
+
✓ Form data loaded successfully
|
|
1015
|
+
</p>
|
|
1016
|
+
)}
|
|
1017
|
+
|
|
1018
|
+
{/* Form Data Preview */}
|
|
1019
|
+
{formDataQuery.data && (
|
|
1020
|
+
<div className="mt-4 p-4 bg-muted rounded-lg">
|
|
1021
|
+
<p className="text-sm font-semibold mb-2">Form Data:</p>
|
|
1022
|
+
<pre className="text-xs overflow-auto max-h-60">
|
|
1023
|
+
{JSON.stringify(formDataQuery.data, null, 2)}
|
|
1024
|
+
</pre>
|
|
1025
|
+
</div>
|
|
1026
|
+
)}
|
|
1027
|
+
</CardContent>
|
|
1028
|
+
</Card>
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Main API Test Page Component
|
|
1033
|
+
export default function ApiTestPage() {
|
|
1034
|
+
return (
|
|
1035
|
+
<SidebarProvider
|
|
1036
|
+
style={
|
|
1037
|
+
{
|
|
1038
|
+
"--sidebar-width": "calc(var(--spacing) * 72)",
|
|
1039
|
+
"--header-height": "calc(var(--spacing) * 12)",
|
|
1040
|
+
} as React.CSSProperties
|
|
1041
|
+
}
|
|
1042
|
+
>
|
|
1043
|
+
<AppSidebar variant="inset" />
|
|
1044
|
+
<SidebarInset>
|
|
1045
|
+
<SiteHeader />
|
|
1046
|
+
<div className="flex flex-1 flex-col">
|
|
1047
|
+
<div className="@container/main flex flex-1 flex-col gap-6 p-6">
|
|
1048
|
+
{/* Page Header */}
|
|
1049
|
+
<div className="flex items-center justify-between">
|
|
1050
|
+
<div>
|
|
1051
|
+
<h1 className="text-3xl font-bold tracking-tight">
|
|
1052
|
+
API Test Page
|
|
1053
|
+
</h1>
|
|
1054
|
+
<p className="text-muted-foreground">
|
|
1055
|
+
Test various API endpoints and hooks. All calls are
|
|
1056
|
+
user-initiated.
|
|
1057
|
+
</p>
|
|
1058
|
+
</div>
|
|
1059
|
+
</div>
|
|
1060
|
+
|
|
1061
|
+
{/* Workbook Test Section */}
|
|
1062
|
+
<WorkbookTestSection />
|
|
1063
|
+
|
|
1064
|
+
{/* Task Test Section */}
|
|
1065
|
+
<TaskTestSection />
|
|
1066
|
+
|
|
1067
|
+
{/* Run Recon Test Section */}
|
|
1068
|
+
<RunReconTestSection />
|
|
1069
|
+
|
|
1070
|
+
{/* File Upload/Download Test Section */}
|
|
1071
|
+
<FileUploadTestSection />
|
|
1072
|
+
|
|
1073
|
+
{/* Form Schema Test Section */}
|
|
1074
|
+
<FormSchemaTestSection />
|
|
1075
|
+
|
|
1076
|
+
{/* Form Data Test Section */}
|
|
1077
|
+
<FormDataTestSection />
|
|
1078
|
+
</div>
|
|
1079
|
+
</div>
|
|
1080
|
+
</SidebarInset>
|
|
1081
|
+
</SidebarProvider>
|
|
1082
|
+
);
|
|
1083
|
+
}
|