@burdenoff/fluidgrids-fe-sdk 2026.1101.3 → 2026.1101.4

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 (62) hide show
  1. package/dist/ExecutionDetailPage-JQCJR5XD.js +25 -0
  2. package/dist/{WorkflowsList-R2JJK7BL.js → ExecutionsListPage-UDDASCDL.js} +8 -9
  3. package/dist/{MissingNodesInstallModal-TALZ7CAJ.js → MissingNodesInstallModal-OSAJLIBE.js} +0 -1
  4. package/dist/{TemplateConfigurationModal-FQIRFBXW.js → TemplateConfigurationModal-SILENYXX.js} +0 -1
  5. package/dist/{TemplateDetailPanel-WH74G7PF.js → TemplateDetailPanel-XJ43LW3G.js} +0 -1
  6. package/dist/{WorkflowBuilder-RJPRUMQR.js → WorkflowBuilder-P52OTD2Y.js} +12 -13
  7. package/dist/{ExecutionsListPage-X4H4FVLN.js → WorkflowsList-QMN25IG4.js} +8 -9
  8. package/dist/{agentTools-MISTH7JI.js → agentTools-F2USMIDU.js} +23 -24
  9. package/dist/assistant.js +0 -1
  10. package/dist/{chunk-26HGYPBC.js → chunk-6EE4PRD6.js} +1 -1
  11. package/dist/{chunk-4QHCXTHW.js → chunk-6JJKKWVD.js} +5 -5
  12. package/dist/{chunk-CGXQVZGY.js → chunk-6XVGLGJ4.js} +1 -1
  13. package/dist/{chunk-HKKSXOFO.js → chunk-7FYXSA76.js} +10 -10
  14. package/dist/{chunk-WF6GMBR4.js → chunk-7MGYG6DR.js} +2 -2
  15. package/dist/{chunk-7KKYIRLH.js → chunk-AOLY5INN.js} +1678 -210
  16. package/dist/{chunk-CRDG2SQQ.js → chunk-AVZ4SXUG.js} +1 -1
  17. package/dist/{chunk-LWLHPVIA.js → chunk-BUWFUPN2.js} +2 -2
  18. package/dist/{chunk-F7DD7BOB.js → chunk-D56WJCK6.js} +4 -4
  19. package/dist/{chunk-IHEV5HTD.js → chunk-DO554TUK.js} +14 -2
  20. package/dist/{chunk-IGRIN7NL.js → chunk-EZRX2PZT.js} +4 -4
  21. package/dist/{chunk-NLYQ3XDE.js → chunk-FLYFZJUC.js} +1 -1
  22. package/dist/{chunk-YKFR7BZJ.js → chunk-FV77SZWB.js} +1 -1
  23. package/dist/{chunk-H7XPXONT.js → chunk-IQZ3DD7U.js} +2 -2
  24. package/dist/{chunk-472HJ3S3.js → chunk-ITLNDVAU.js} +4 -4
  25. package/dist/{chunk-G634XDO3.js → chunk-K5TN3BKD.js} +1 -1
  26. package/dist/{chunk-DQ2ZCXYX.js → chunk-KEPQLNP6.js} +23 -23
  27. package/dist/{chunk-LYTR6IQO.js → chunk-LFCF5KTH.js} +2 -2
  28. package/dist/{chunk-MR2B67NW.js → chunk-LGMSYVMT.js} +1 -1
  29. package/dist/{chunk-W7MTSATB.js → chunk-LIVFWFT4.js} +949 -43
  30. package/dist/{chunk-3ERT6FQK.js → chunk-O4RZZXVP.js} +3 -3
  31. package/dist/{chunk-JNZCXFLD.js → chunk-PC66C2AA.js} +1 -1
  32. package/dist/{chunk-YSXNJGCY.js → chunk-QBYLI3HK.js} +9 -9
  33. package/dist/{chunk-T2UUYYVJ.js → chunk-QRECENSK.js} +4 -4
  34. package/dist/{chunk-OSQ3OCR3.js → chunk-QUIZ5IP4.js} +2 -2
  35. package/dist/{chunk-37VUN74D.js → chunk-UN6NUIBV.js} +4 -4
  36. package/dist/{chunk-PZ45H72P.js → chunk-UWCGAXYV.js} +1 -1
  37. package/dist/{chunk-NZJWKVER.js → chunk-V4TI5JMD.js} +1 -1
  38. package/dist/{chunk-IA2ZCHNQ.js → chunk-WKNYQ4M6.js} +2 -2
  39. package/dist/{chunk-REO4S5MY.js → chunk-WN4FBSFD.js} +4 -4
  40. package/dist/{chunk-JKBCLBHY.js → chunk-XGMGCOTR.js} +1 -1
  41. package/dist/{client-T7BHWM2H.js → client-EYQDMR4O.js} +0 -1
  42. package/dist/{code-editor-field-JKCUR6BI.js → code-editor-field-XWUVOKTA.js} +0 -1
  43. package/dist/{config-VM7FTHMZ.js → config-3DBXLCK3.js} +0 -1
  44. package/dist/executions.js +13 -14
  45. package/dist/{global-client-KLOVTVPP.js → global-client-O2HCG5CJ.js} +0 -1
  46. package/dist/{global-operations-RAFTISSY.js → global-operations-BZDHTSYP.js} +0 -1
  47. package/dist/history.js +4 -5
  48. package/dist/index.d.ts +16773 -2663
  49. package/dist/index.js +67 -68
  50. package/dist/{node-detail-view-PCYFQX62.js → node-detail-view-NTWGYZMB.js} +9 -10
  51. package/dist/nodes.js +2 -3
  52. package/dist/observability.js +6 -7
  53. package/dist/{quick-config-panel-BRZZHOSI.js → quick-config-panel-ZMCB6VXB.js} +6 -7
  54. package/dist/settings.js +6 -7
  55. package/dist/{template-input-applicator-TI7PWHK3.js → template-input-applicator-OBQUTYDA.js} +0 -1
  56. package/dist/templates.js +11 -12
  57. package/dist/workflow-builder.js +13 -14
  58. package/dist/workflows-list.js +8 -9
  59. package/package.json +4 -2
  60. package/dist/ExecutionDetailPage-Q77U6YJO.js +0 -26
  61. package/dist/chunk-62GWEYJ5.js +0 -7
  62. package/dist/chunk-WYCB6OQL.js +0 -19709
@@ -1,18 +1,20 @@
1
- import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-26HGYPBC.js';
2
- import { useExecutions } from './chunk-LYTR6IQO.js';
3
- import { useExportWorkflowAs, downloadWorkflowExport, importAcceptAttribute, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-WF6GMBR4.js';
1
+ import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-6EE4PRD6.js';
2
+ import { useExecutions } from './chunk-LFCF5KTH.js';
3
+ import { useExportWorkflowAs, downloadWorkflowExport, importAcceptAttribute, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-7MGYG6DR.js';
4
4
  import { workflowsListControls } from './chunk-FNZZ5JJL.js';
5
- import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-LWLHPVIA.js';
5
+ import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-BUWFUPN2.js';
6
6
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
7
7
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
8
- import { createThenOpen, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, isQuotaExhaustedFailure } from './chunk-NZJWKVER.js';
8
+ import { createThenOpen, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, throwIfResultError, isQuotaExhaustedFailure } from './chunk-V4TI5JMD.js';
9
9
  import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-ZUVFD5KV.js';
10
+ import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-DO554TUK.js';
10
11
  import { useTr } from './chunk-UULVIT25.js';
11
- import { useState, useRef, useCallback, useMemo } from 'react';
12
+ import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
13
+ import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
12
14
  import { useNavigate } from 'react-router';
13
15
  import { v4 } from 'uuid';
14
16
  import { Icon } from '@iconify/react';
15
- import { NextSteps, Button, Badge, Input, IllustratedEmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Label, Textarea, DialogFooter, Skeleton, TooltipProvider, Card, Tooltip, TooltipTrigger, TooltipContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@burdenoff/fe-libs/ui';
17
+ import { NextSteps, Button, Badge, Input, IllustratedEmptyState, Checkbox, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Label, Textarea, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectSeparator, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, Skeleton, TooltipProvider, Card, Tooltip, TooltipTrigger, TooltipContent, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@burdenoff/fe-libs/ui';
16
18
  import { cn } from '@burdenoff/fe-libs/utils';
17
19
  import { TagBadge } from '@burdenoff/fe-libs/tag';
18
20
  import { toast } from 'sonner';
@@ -1231,6 +1233,834 @@ function WorkflowImportDialog({
1231
1233
  }
1232
1234
  );
1233
1235
  }
1236
+ function useWorkflowFolders() {
1237
+ const [folders, setFolders] = useState([]);
1238
+ const [loading, setLoading] = useState(true);
1239
+ const [error, setError] = useState(null);
1240
+ const fetchData = useCallback(async () => {
1241
+ setLoading(true);
1242
+ setError(null);
1243
+ try {
1244
+ const client = getFluidGridsClient();
1245
+ const result = await client.query({
1246
+ query: WorkflowFoldersDocument,
1247
+ fetchPolicy: "network-only"
1248
+ });
1249
+ setFolders(result.data?.workflowFolders ?? []);
1250
+ } catch (err) {
1251
+ setError(err);
1252
+ } finally {
1253
+ setLoading(false);
1254
+ }
1255
+ }, []);
1256
+ useEffect(() => {
1257
+ fetchData();
1258
+ }, [fetchData]);
1259
+ return { folders, loading, error, refetch: fetchData };
1260
+ }
1261
+ function useWorkflowProjects() {
1262
+ const [projects, setProjects] = useState([]);
1263
+ const [loading, setLoading] = useState(true);
1264
+ const [error, setError] = useState(null);
1265
+ const fetchData = useCallback(async () => {
1266
+ setLoading(true);
1267
+ setError(null);
1268
+ try {
1269
+ const client = getFluidGridsClient();
1270
+ const result = await client.query({
1271
+ query: WorkflowProjectsDocument,
1272
+ fetchPolicy: "network-only"
1273
+ });
1274
+ setProjects(result.data?.workflowProjects ?? []);
1275
+ } catch (err) {
1276
+ setError(err);
1277
+ } finally {
1278
+ setLoading(false);
1279
+ }
1280
+ }, []);
1281
+ useEffect(() => {
1282
+ fetchData();
1283
+ }, [fetchData]);
1284
+ return { projects, loading, error, refetch: fetchData };
1285
+ }
1286
+ function useWorkflowFolderActions() {
1287
+ const [loading, setLoading] = useState(false);
1288
+ const [error, setError] = useState(null);
1289
+ const createFolder = useCallback(async (input) => {
1290
+ setLoading(true);
1291
+ setError(null);
1292
+ try {
1293
+ const client = getFluidGridsClient();
1294
+ const result = throwIfResultError(
1295
+ await client.mutate({
1296
+ mutation: CreateWorkflowFolderDocument,
1297
+ variables: { input }
1298
+ })
1299
+ );
1300
+ return result.data?.createWorkflowFolder ?? null;
1301
+ } catch (err) {
1302
+ setError(err);
1303
+ return null;
1304
+ } finally {
1305
+ setLoading(false);
1306
+ }
1307
+ }, []);
1308
+ const renameFolder = useCallback(async (id, name) => {
1309
+ setLoading(true);
1310
+ setError(null);
1311
+ try {
1312
+ const client = getFluidGridsClient();
1313
+ const result = throwIfResultError(
1314
+ await client.mutate({
1315
+ mutation: RenameWorkflowFolderDocument,
1316
+ variables: { id, name }
1317
+ })
1318
+ );
1319
+ return result.data?.renameWorkflowFolder ?? null;
1320
+ } catch (err) {
1321
+ setError(err);
1322
+ return null;
1323
+ } finally {
1324
+ setLoading(false);
1325
+ }
1326
+ }, []);
1327
+ const moveFolder = useCallback(
1328
+ async (id, parentId) => {
1329
+ setLoading(true);
1330
+ setError(null);
1331
+ try {
1332
+ const client = getFluidGridsClient();
1333
+ const result = throwIfResultError(
1334
+ await client.mutate({
1335
+ mutation: MoveWorkflowFolderDocument,
1336
+ variables: { id, parentId }
1337
+ })
1338
+ );
1339
+ return result.data?.moveWorkflowFolder ?? null;
1340
+ } catch (err) {
1341
+ setError(err);
1342
+ return null;
1343
+ } finally {
1344
+ setLoading(false);
1345
+ }
1346
+ },
1347
+ []
1348
+ );
1349
+ const deleteFolder = useCallback(async (id) => {
1350
+ setLoading(true);
1351
+ setError(null);
1352
+ try {
1353
+ const client = getFluidGridsClient();
1354
+ const result = throwIfResultError(
1355
+ await client.mutate({
1356
+ mutation: DeleteWorkflowFolderDocument,
1357
+ variables: { id }
1358
+ })
1359
+ );
1360
+ return result.data?.deleteWorkflowFolder ?? false;
1361
+ } catch (err) {
1362
+ setError(err);
1363
+ return false;
1364
+ } finally {
1365
+ setLoading(false);
1366
+ }
1367
+ }, []);
1368
+ return {
1369
+ createFolder,
1370
+ renameFolder,
1371
+ moveFolder,
1372
+ deleteFolder,
1373
+ loading,
1374
+ error
1375
+ };
1376
+ }
1377
+ function useWorkflowProjectActions() {
1378
+ const [loading, setLoading] = useState(false);
1379
+ const [error, setError] = useState(null);
1380
+ const createProject = useCallback(
1381
+ async (input) => {
1382
+ setLoading(true);
1383
+ setError(null);
1384
+ try {
1385
+ const client = getFluidGridsClient();
1386
+ const result = throwIfResultError(
1387
+ await client.mutate({
1388
+ mutation: CreateWorkflowProjectDocument,
1389
+ variables: { input }
1390
+ })
1391
+ );
1392
+ return result.data?.createWorkflowProject ?? null;
1393
+ } catch (err) {
1394
+ setError(err);
1395
+ return null;
1396
+ } finally {
1397
+ setLoading(false);
1398
+ }
1399
+ },
1400
+ []
1401
+ );
1402
+ const renameProject = useCallback(
1403
+ async (id, name, description) => {
1404
+ setLoading(true);
1405
+ setError(null);
1406
+ try {
1407
+ const client = getFluidGridsClient();
1408
+ const result = throwIfResultError(
1409
+ await client.mutate({
1410
+ mutation: RenameWorkflowProjectDocument,
1411
+ variables: { id, name, description }
1412
+ })
1413
+ );
1414
+ return result.data?.renameWorkflowProject ?? null;
1415
+ } catch (err) {
1416
+ setError(err);
1417
+ return null;
1418
+ } finally {
1419
+ setLoading(false);
1420
+ }
1421
+ },
1422
+ []
1423
+ );
1424
+ const deleteProject = useCallback(async (id) => {
1425
+ setLoading(true);
1426
+ setError(null);
1427
+ try {
1428
+ const client = getFluidGridsClient();
1429
+ const result = throwIfResultError(
1430
+ await client.mutate({
1431
+ mutation: DeleteWorkflowProjectDocument,
1432
+ variables: { id }
1433
+ })
1434
+ );
1435
+ return result.data?.deleteWorkflowProject ?? false;
1436
+ } catch (err) {
1437
+ setError(err);
1438
+ return false;
1439
+ } finally {
1440
+ setLoading(false);
1441
+ }
1442
+ }, []);
1443
+ return { createProject, renameProject, deleteProject, loading, error };
1444
+ }
1445
+ function useBulkWorkflowActions() {
1446
+ const [loading, setLoading] = useState(false);
1447
+ const [error, setError] = useState(null);
1448
+ const bulkMoveToFolder = useCallback(
1449
+ async (workflowIds, folderId) => {
1450
+ setLoading(true);
1451
+ setError(null);
1452
+ try {
1453
+ const client = getFluidGridsClient();
1454
+ const result = throwIfResultError(
1455
+ await client.mutate({
1456
+ mutation: BulkMoveWorkflowsToFolderDocument,
1457
+ variables: { folderId, workflowIds },
1458
+ refetchQueries: ["WorkflowDefinitions"]
1459
+ })
1460
+ );
1461
+ return result.data?.bulkMoveWorkflowsToFolder ?? null;
1462
+ } catch (err) {
1463
+ setError(err);
1464
+ return null;
1465
+ } finally {
1466
+ setLoading(false);
1467
+ }
1468
+ },
1469
+ []
1470
+ );
1471
+ const bulkAssignToProject = useCallback(
1472
+ async (workflowIds, projectId) => {
1473
+ setLoading(true);
1474
+ setError(null);
1475
+ try {
1476
+ const client = getFluidGridsClient();
1477
+ const result = throwIfResultError(
1478
+ await client.mutate({
1479
+ mutation: BulkAssignWorkflowsToProjectDocument,
1480
+ variables: { projectId, workflowIds },
1481
+ refetchQueries: ["WorkflowDefinitions"]
1482
+ })
1483
+ );
1484
+ return result.data?.bulkAssignWorkflowsToProject ?? null;
1485
+ } catch (err) {
1486
+ setError(err);
1487
+ return null;
1488
+ } finally {
1489
+ setLoading(false);
1490
+ }
1491
+ },
1492
+ []
1493
+ );
1494
+ const bulkDelete = useCallback(async (workflowIds) => {
1495
+ setLoading(true);
1496
+ setError(null);
1497
+ try {
1498
+ const client = getFluidGridsClient();
1499
+ const result = throwIfResultError(
1500
+ await client.mutate({
1501
+ mutation: BulkDeleteWorkflowsDocument,
1502
+ variables: { workflowIds },
1503
+ refetchQueries: ["WorkflowDefinitions"]
1504
+ })
1505
+ );
1506
+ return result.data?.bulkDeleteWorkflows ?? null;
1507
+ } catch (err) {
1508
+ setError(err);
1509
+ return null;
1510
+ } finally {
1511
+ setLoading(false);
1512
+ }
1513
+ }, []);
1514
+ return {
1515
+ bulkMoveToFolder,
1516
+ bulkAssignToProject,
1517
+ bulkDelete,
1518
+ loading,
1519
+ error
1520
+ };
1521
+ }
1522
+ function FolderRow({
1523
+ folder,
1524
+ depth,
1525
+ selectedFolderId,
1526
+ onSelect,
1527
+ onCreateChild,
1528
+ onRename,
1529
+ onDelete
1530
+ }) {
1531
+ const tr = useTr();
1532
+ const [expanded, setExpanded] = useState(true);
1533
+ const hasChildren = (folder.children ?? []).length > 0;
1534
+ return /* @__PURE__ */ jsxs("div", { children: [
1535
+ /* @__PURE__ */ jsxs(
1536
+ "div",
1537
+ {
1538
+ className: cn(
1539
+ "group flex items-center gap-1 rounded-md px-2 py-1.5 text-sm",
1540
+ selectedFolderId === folder.id ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-card hover:text-foreground"
1541
+ ),
1542
+ style: { paddingLeft: `${8 + depth * 14}px` },
1543
+ children: [
1544
+ /* @__PURE__ */ jsx(
1545
+ "button",
1546
+ {
1547
+ type: "button",
1548
+ onClick: () => setExpanded((v) => !v),
1549
+ className: cn(
1550
+ "flex size-4 shrink-0 items-center justify-center",
1551
+ !hasChildren && "invisible"
1552
+ ),
1553
+ "aria-label": tr(
1554
+ "fluidgrids.workflowsList.folders.toggleAriaLabel",
1555
+ "Toggle folder"
1556
+ ),
1557
+ children: /* @__PURE__ */ jsx(
1558
+ Icon,
1559
+ {
1560
+ icon: expanded ? "mynaui:chevron-down" : "mynaui:chevron-right",
1561
+ className: "size-3.5"
1562
+ }
1563
+ )
1564
+ }
1565
+ ),
1566
+ /* @__PURE__ */ jsxs(
1567
+ "button",
1568
+ {
1569
+ type: "button",
1570
+ onClick: () => onSelect(folder.id),
1571
+ className: "flex min-w-0 flex-1 items-center gap-1.5 truncate text-left",
1572
+ children: [
1573
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:folder", className: "size-4 shrink-0" }),
1574
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: folder.name }),
1575
+ /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "ml-1 font-mono text-[10px]", children: folder.workflowCount })
1576
+ ]
1577
+ }
1578
+ ),
1579
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1580
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1581
+ "button",
1582
+ {
1583
+ type: "button",
1584
+ className: "invisible flex size-5 shrink-0 items-center justify-center rounded group-hover:visible hover:bg-muted",
1585
+ "aria-label": tr(
1586
+ "fluidgrids.workflowsList.folders.menuAriaLabel",
1587
+ "Folder actions"
1588
+ ),
1589
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:dots", className: "size-3.5" })
1590
+ }
1591
+ ) }),
1592
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", children: [
1593
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onCreateChild(folder.id), children: tr(
1594
+ "fluidgrids.workflowsList.folders.newSubfolder",
1595
+ "New subfolder"
1596
+ ) }),
1597
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onRename(folder), children: tr("fluidgrids.workflowsList.folders.rename", "Rename") }),
1598
+ /* @__PURE__ */ jsx(
1599
+ DropdownMenuItem,
1600
+ {
1601
+ onClick: () => onDelete(folder),
1602
+ className: "text-destructive",
1603
+ children: tr("fluidgrids.workflowsList.folders.delete", "Delete")
1604
+ }
1605
+ )
1606
+ ] })
1607
+ ] })
1608
+ ]
1609
+ }
1610
+ ),
1611
+ expanded && (folder.children ?? []).map((child) => /* @__PURE__ */ jsx(
1612
+ FolderRow,
1613
+ {
1614
+ folder: child,
1615
+ depth: depth + 1,
1616
+ selectedFolderId,
1617
+ onSelect,
1618
+ onCreateChild,
1619
+ onRename,
1620
+ onDelete
1621
+ },
1622
+ child.id
1623
+ ))
1624
+ ] });
1625
+ }
1626
+ function WorkflowFolderSidebar({
1627
+ selectedFolderId,
1628
+ onSelectFolder
1629
+ }) {
1630
+ const tr = useTr();
1631
+ const { folders, loading, refetch } = useWorkflowFolders();
1632
+ const { createFolder, renameFolder, deleteFolder } = useWorkflowFolderActions();
1633
+ const [dialog, setDialog] = useState(null);
1634
+ const [name, setName] = useState("");
1635
+ const [deleteTarget, setDeleteTarget] = useState(null);
1636
+ const openCreate = (parentId) => {
1637
+ setName("");
1638
+ setDialog({ mode: "create", parentId });
1639
+ };
1640
+ const openRename = (folder) => {
1641
+ setName(folder.name);
1642
+ setDialog({ mode: "rename", parentId: folder.parentId ?? null, folder });
1643
+ };
1644
+ const submitDialog = async () => {
1645
+ if (!dialog || !name.trim()) return;
1646
+ if (dialog.mode === "create") {
1647
+ const created = await createFolder({
1648
+ name: name.trim(),
1649
+ parentId: dialog.parentId
1650
+ });
1651
+ if (!created) {
1652
+ toast.error(
1653
+ tr(
1654
+ "fluidgrids.workflowsList.folders.createError",
1655
+ "Couldn't create the folder"
1656
+ )
1657
+ );
1658
+ return;
1659
+ }
1660
+ } else if (dialog.folder) {
1661
+ const renamed = await renameFolder(dialog.folder.id, name.trim());
1662
+ if (!renamed) {
1663
+ toast.error(
1664
+ tr(
1665
+ "fluidgrids.workflowsList.folders.renameError",
1666
+ "Couldn't rename the folder"
1667
+ )
1668
+ );
1669
+ return;
1670
+ }
1671
+ }
1672
+ setDialog(null);
1673
+ void refetch();
1674
+ };
1675
+ const confirmDelete = async () => {
1676
+ if (!deleteTarget) return;
1677
+ const ok = await deleteFolder(deleteTarget.id);
1678
+ if (!ok) {
1679
+ toast.error(
1680
+ tr(
1681
+ "fluidgrids.workflowsList.folders.deleteError",
1682
+ "Couldn't delete the folder"
1683
+ )
1684
+ );
1685
+ } else {
1686
+ if (selectedFolderId === deleteTarget.id) onSelectFolder(null);
1687
+ void refetch();
1688
+ }
1689
+ setDeleteTarget(null);
1690
+ };
1691
+ return /* @__PURE__ */ jsxs(
1692
+ "aside",
1693
+ {
1694
+ className: "flex w-56 shrink-0 flex-col gap-1 border-r border-border p-2",
1695
+ "data-tour": "fluidgrids-list-folders",
1696
+ children: [
1697
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-2 py-1", children: [
1698
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase text-muted-foreground", children: tr("fluidgrids.workflowsList.folders.title", "Folders") }),
1699
+ /* @__PURE__ */ jsx(
1700
+ "button",
1701
+ {
1702
+ type: "button",
1703
+ onClick: () => openCreate(null),
1704
+ className: "flex size-5 items-center justify-center rounded hover:bg-muted",
1705
+ "aria-label": tr(
1706
+ "fluidgrids.workflowsList.folders.newFolderAriaLabel",
1707
+ "New folder"
1708
+ ),
1709
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:plus", className: "size-3.5" })
1710
+ }
1711
+ )
1712
+ ] }),
1713
+ /* @__PURE__ */ jsxs(
1714
+ "button",
1715
+ {
1716
+ type: "button",
1717
+ onClick: () => onSelectFolder(null),
1718
+ className: cn(
1719
+ "flex items-center gap-1.5 rounded-md px-2 py-1.5 text-left text-sm",
1720
+ selectedFolderId === null ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-card hover:text-foreground"
1721
+ ),
1722
+ children: [
1723
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:grid", className: "size-4" }),
1724
+ tr("fluidgrids.workflowsList.folders.allWorkflows", "All workflows")
1725
+ ]
1726
+ }
1727
+ ),
1728
+ loading ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: tr("fluidgrids.workflowsList.folders.loading", "Loading\u2026") }) : folders.map((folder) => /* @__PURE__ */ jsx(
1729
+ FolderRow,
1730
+ {
1731
+ folder,
1732
+ depth: 0,
1733
+ selectedFolderId,
1734
+ onSelect: onSelectFolder,
1735
+ onCreateChild: openCreate,
1736
+ onRename: openRename,
1737
+ onDelete: setDeleteTarget
1738
+ },
1739
+ folder.id
1740
+ )),
1741
+ /* @__PURE__ */ jsx(
1742
+ Dialog,
1743
+ {
1744
+ open: dialog !== null,
1745
+ onOpenChange: (open) => !open && setDialog(null),
1746
+ children: /* @__PURE__ */ jsxs(DialogContent, { children: [
1747
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1748
+ /* @__PURE__ */ jsx(DialogTitle, { children: dialog?.mode === "rename" ? tr(
1749
+ "fluidgrids.workflowsList.folders.renameTitle",
1750
+ "Rename folder"
1751
+ ) : tr(
1752
+ "fluidgrids.workflowsList.folders.createTitle",
1753
+ "New folder"
1754
+ ) }),
1755
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
1756
+ "fluidgrids.workflowsList.folders.nameDescription",
1757
+ "Folder name"
1758
+ ) })
1759
+ ] }),
1760
+ /* @__PURE__ */ jsx(
1761
+ Input,
1762
+ {
1763
+ autoFocus: true,
1764
+ value: name,
1765
+ onChange: (e) => setName(e.target.value),
1766
+ onKeyDown: (e) => {
1767
+ if (e.key === "Enter") void submitDialog();
1768
+ },
1769
+ placeholder: tr(
1770
+ "fluidgrids.workflowsList.folders.namePlaceholder",
1771
+ "e.g. Marketing"
1772
+ )
1773
+ }
1774
+ ),
1775
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
1776
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setDialog(null), children: tr("fluidgrids.workflowsList.folders.cancel", "Cancel") }),
1777
+ /* @__PURE__ */ jsx(Button, { onClick: () => void submitDialog(), disabled: !name.trim(), children: tr("fluidgrids.workflowsList.folders.save", "Save") })
1778
+ ] })
1779
+ ] })
1780
+ }
1781
+ ),
1782
+ /* @__PURE__ */ jsx(
1783
+ Dialog,
1784
+ {
1785
+ open: deleteTarget !== null,
1786
+ onOpenChange: (open) => !open && setDeleteTarget(null),
1787
+ children: /* @__PURE__ */ jsxs(DialogContent, { children: [
1788
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1789
+ /* @__PURE__ */ jsx(DialogTitle, { children: tr(
1790
+ "fluidgrids.workflowsList.folders.deleteTitle",
1791
+ "Delete folder?"
1792
+ ) }),
1793
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
1794
+ "fluidgrids.workflowsList.folders.deleteDescription",
1795
+ "Its workflows move to the top level; child folders move up a level. This can't be undone."
1796
+ ) })
1797
+ ] }),
1798
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
1799
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setDeleteTarget(null), children: tr("fluidgrids.workflowsList.folders.cancel", "Cancel") }),
1800
+ /* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: () => void confirmDelete(), children: tr("fluidgrids.workflowsList.folders.delete", "Delete") })
1801
+ ] })
1802
+ ] })
1803
+ }
1804
+ )
1805
+ ]
1806
+ }
1807
+ );
1808
+ }
1809
+ var ALL_PROJECTS_VALUE = "__all__";
1810
+ var NEW_PROJECT_VALUE = "__new__";
1811
+ function WorkflowProjectSelect({
1812
+ selectedProjectId,
1813
+ onSelectProject
1814
+ }) {
1815
+ const tr = useTr();
1816
+ const { projects, refetch } = useWorkflowProjects();
1817
+ const { createProject } = useWorkflowProjectActions();
1818
+ const [creating, setCreating] = useState(false);
1819
+ const [name, setName] = useState("");
1820
+ const handleChange = (value) => {
1821
+ if (value === NEW_PROJECT_VALUE) {
1822
+ setName("");
1823
+ setCreating(true);
1824
+ return;
1825
+ }
1826
+ onSelectProject(value === ALL_PROJECTS_VALUE ? null : value);
1827
+ };
1828
+ const submitCreate = async () => {
1829
+ if (!name.trim()) return;
1830
+ const created = await createProject({ name: name.trim() });
1831
+ if (!created) {
1832
+ toast.error(
1833
+ tr(
1834
+ "fluidgrids.workflowsList.projects.createError",
1835
+ "Couldn't create the project"
1836
+ )
1837
+ );
1838
+ return;
1839
+ }
1840
+ setCreating(false);
1841
+ void refetch();
1842
+ onSelectProject(created.id);
1843
+ };
1844
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1845
+ /* @__PURE__ */ jsxs(
1846
+ Select,
1847
+ {
1848
+ value: selectedProjectId ?? ALL_PROJECTS_VALUE,
1849
+ onValueChange: handleChange,
1850
+ children: [
1851
+ /* @__PURE__ */ jsx(
1852
+ SelectTrigger,
1853
+ {
1854
+ className: "w-44",
1855
+ "aria-label": tr(
1856
+ "fluidgrids.workflowsList.projects.selectAriaLabel",
1857
+ "Project"
1858
+ ),
1859
+ children: /* @__PURE__ */ jsx(
1860
+ SelectValue,
1861
+ {
1862
+ placeholder: tr(
1863
+ "fluidgrids.workflowsList.projects.allProjects",
1864
+ "All projects"
1865
+ )
1866
+ }
1867
+ )
1868
+ }
1869
+ ),
1870
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
1871
+ /* @__PURE__ */ jsx(SelectItem, { value: ALL_PROJECTS_VALUE, children: tr(
1872
+ "fluidgrids.workflowsList.projects.allProjects",
1873
+ "All projects"
1874
+ ) }),
1875
+ projects.map((project) => /* @__PURE__ */ jsxs(SelectItem, { value: project.id, children: [
1876
+ project.name,
1877
+ " (",
1878
+ project.workflowCount,
1879
+ ")"
1880
+ ] }, project.id)),
1881
+ /* @__PURE__ */ jsx(SelectSeparator, {}),
1882
+ /* @__PURE__ */ jsx(SelectItem, { value: NEW_PROJECT_VALUE, children: tr(
1883
+ "fluidgrids.workflowsList.projects.newProject",
1884
+ "+ New project"
1885
+ ) })
1886
+ ] })
1887
+ ]
1888
+ }
1889
+ ),
1890
+ /* @__PURE__ */ jsx(Dialog, { open: creating, onOpenChange: setCreating, children: /* @__PURE__ */ jsxs(DialogContent, { children: [
1891
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1892
+ /* @__PURE__ */ jsx(DialogTitle, { children: tr(
1893
+ "fluidgrids.workflowsList.projects.createTitle",
1894
+ "New project"
1895
+ ) }),
1896
+ /* @__PURE__ */ jsx(DialogDescription, { children: tr(
1897
+ "fluidgrids.workflowsList.projects.nameDescription",
1898
+ "Project name"
1899
+ ) })
1900
+ ] }),
1901
+ /* @__PURE__ */ jsx(
1902
+ Input,
1903
+ {
1904
+ autoFocus: true,
1905
+ value: name,
1906
+ onChange: (e) => setName(e.target.value),
1907
+ onKeyDown: (e) => {
1908
+ if (e.key === "Enter") void submitCreate();
1909
+ },
1910
+ placeholder: tr(
1911
+ "fluidgrids.workflowsList.projects.namePlaceholder",
1912
+ "e.g. Q4 launch"
1913
+ )
1914
+ }
1915
+ ),
1916
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
1917
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setCreating(false), children: tr("fluidgrids.workflowsList.projects.cancel", "Cancel") }),
1918
+ /* @__PURE__ */ jsx(Button, { onClick: () => void submitCreate(), disabled: !name.trim(), children: tr("fluidgrids.workflowsList.projects.save", "Save") })
1919
+ ] })
1920
+ ] }) })
1921
+ ] });
1922
+ }
1923
+ var UNFILED_VALUE = "__unfiled__";
1924
+ function WorkflowBulkActionsBar({
1925
+ selectedIds,
1926
+ onDone
1927
+ }) {
1928
+ const tr = useTr();
1929
+ const { folders } = useWorkflowFolders();
1930
+ const { projects } = useWorkflowProjects();
1931
+ const { bulkMoveToFolder, bulkAssignToProject, bulkDelete, loading } = useBulkWorkflowActions();
1932
+ const [confirmingDelete, setConfirmingDelete] = useState(false);
1933
+ const flatFolders = flattenFolders(folders);
1934
+ const reportFailures = (result) => {
1935
+ if (result && result.failedIds.length > 0) {
1936
+ toast.error(
1937
+ tr(
1938
+ "fluidgrids.workflowsList.bulk.partialFailure",
1939
+ "{{count}} workflow(s) couldn't be updated",
1940
+ { count: result.failedIds.length }
1941
+ )
1942
+ );
1943
+ }
1944
+ };
1945
+ const handleMove = async (folderId) => {
1946
+ const result = await bulkMoveToFolder(
1947
+ selectedIds,
1948
+ folderId === UNFILED_VALUE ? null : folderId
1949
+ );
1950
+ reportFailures(result);
1951
+ onDone();
1952
+ };
1953
+ const handleAssign = async (projectId) => {
1954
+ const result = await bulkAssignToProject(
1955
+ selectedIds,
1956
+ projectId === UNFILED_VALUE ? null : projectId
1957
+ );
1958
+ reportFailures(result);
1959
+ onDone();
1960
+ };
1961
+ const handleDelete = async () => {
1962
+ setConfirmingDelete(false);
1963
+ const result = await bulkDelete(selectedIds);
1964
+ reportFailures(result);
1965
+ onDone();
1966
+ };
1967
+ return /* @__PURE__ */ jsxs(
1968
+ "div",
1969
+ {
1970
+ className: "flex flex-wrap items-center gap-2 rounded-lg border border-border bg-card px-3 py-2",
1971
+ "data-tour": "fluidgrids-list-bulk-bar",
1972
+ children: [
1973
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: tr(
1974
+ "fluidgrids.workflowsList.bulk.selectedCount",
1975
+ "{{count}} selected",
1976
+ {
1977
+ count: selectedIds.length
1978
+ }
1979
+ ) }),
1980
+ /* @__PURE__ */ jsxs(Select, { onValueChange: (v) => void handleMove(v), disabled: loading, children: [
1981
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-40 text-xs", children: /* @__PURE__ */ jsx(
1982
+ SelectValue,
1983
+ {
1984
+ placeholder: tr(
1985
+ "fluidgrids.workflowsList.bulk.moveToFolder",
1986
+ "Move to folder"
1987
+ )
1988
+ }
1989
+ ) }),
1990
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
1991
+ /* @__PURE__ */ jsx(SelectItem, { value: UNFILED_VALUE, children: tr("fluidgrids.workflowsList.bulk.unfiled", "Unfiled") }),
1992
+ flatFolders.map((folder) => /* @__PURE__ */ jsx(SelectItem, { value: folder.id, children: folder.label }, folder.id))
1993
+ ] })
1994
+ ] }),
1995
+ /* @__PURE__ */ jsxs(Select, { onValueChange: (v) => void handleAssign(v), disabled: loading, children: [
1996
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-40 text-xs", children: /* @__PURE__ */ jsx(
1997
+ SelectValue,
1998
+ {
1999
+ placeholder: tr(
2000
+ "fluidgrids.workflowsList.bulk.assignToProject",
2001
+ "Assign to project"
2002
+ )
2003
+ }
2004
+ ) }),
2005
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
2006
+ /* @__PURE__ */ jsx(SelectItem, { value: UNFILED_VALUE, children: tr("fluidgrids.workflowsList.bulk.noProject", "No project") }),
2007
+ projects.map((project) => /* @__PURE__ */ jsx(SelectItem, { value: project.id, children: project.name }, project.id))
2008
+ ] })
2009
+ ] }),
2010
+ /* @__PURE__ */ jsxs(
2011
+ Button,
2012
+ {
2013
+ variant: "outline",
2014
+ size: "sm",
2015
+ className: "h-8 text-destructive",
2016
+ disabled: loading,
2017
+ onClick: () => setConfirmingDelete(true),
2018
+ children: [
2019
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:trash", className: "size-3.5" }),
2020
+ tr("fluidgrids.workflowsList.bulk.delete", "Delete")
2021
+ ]
2022
+ }
2023
+ ),
2024
+ /* @__PURE__ */ jsx(
2025
+ Button,
2026
+ {
2027
+ variant: "ghost",
2028
+ size: "sm",
2029
+ className: "h-8 ml-auto",
2030
+ onClick: onDone,
2031
+ children: tr("fluidgrids.workflowsList.bulk.cancel", "Cancel")
2032
+ }
2033
+ ),
2034
+ /* @__PURE__ */ jsx(AlertDialog, { open: confirmingDelete, onOpenChange: setConfirmingDelete, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
2035
+ /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
2036
+ /* @__PURE__ */ jsx(AlertDialogTitle, { children: tr(
2037
+ "fluidgrids.workflowsList.bulk.deleteConfirmTitle",
2038
+ "Delete {{count}} workflow(s)?",
2039
+ { count: selectedIds.length }
2040
+ ) }),
2041
+ /* @__PURE__ */ jsx(AlertDialogDescription, { children: tr(
2042
+ "fluidgrids.workflowsList.bulk.deleteConfirmDescription",
2043
+ "This can't be undone."
2044
+ ) })
2045
+ ] }),
2046
+ /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
2047
+ /* @__PURE__ */ jsx(AlertDialogCancel, { children: tr("fluidgrids.workflowsList.bulk.cancel", "Cancel") }),
2048
+ /* @__PURE__ */ jsx(AlertDialogAction, { onClick: () => void handleDelete(), children: tr("fluidgrids.workflowsList.bulk.delete", "Delete") })
2049
+ ] })
2050
+ ] }) })
2051
+ ]
2052
+ }
2053
+ );
2054
+ }
2055
+ function flattenFolders(folders, depth = 0) {
2056
+ return folders.flatMap((folder) => [
2057
+ { id: folder.id, label: `${"\u2014 ".repeat(depth)}${folder.name}` },
2058
+ ...flattenFolders(
2059
+ folder.children ?? [],
2060
+ depth + 1
2061
+ )
2062
+ ]);
2063
+ }
1234
2064
  function firstWorkflowSteps({
1235
2065
  progress,
1236
2066
  canCreate,
@@ -1460,6 +2290,10 @@ function WorkflowsList() {
1460
2290
  const [search, setSearch] = useState("");
1461
2291
  const [statusFilter, setStatusFilter] = useState(null);
1462
2292
  const [tagFilter, setTagFilter] = useState(null);
2293
+ const [folderFilter, setFolderFilter] = useState(null);
2294
+ const [projectFilter, setProjectFilter] = useState(null);
2295
+ const [selectMode, setSelectMode] = useState(false);
2296
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
1463
2297
  const presentStatuses = useMemo(() => {
1464
2298
  const seen = new Set(workflows.map((w) => w.status ?? "DRAFT"));
1465
2299
  return STATUS_FILTERS.filter((s) => seen.has(s.value));
@@ -1484,10 +2318,33 @@ function WorkflowsList() {
1484
2318
  if (statusFilter && (w.status ?? "DRAFT") !== statusFilter) return false;
1485
2319
  if (tagFilter && !(tagsByKey[w.workflowKey] ?? []).some((a) => a.tagId === tagFilter))
1486
2320
  return false;
2321
+ if (folderFilter && w.folderId !== folderFilter) return false;
2322
+ if (projectFilter && w.projectId !== projectFilter) return false;
1487
2323
  if (!q) return true;
1488
2324
  return [w.name, w.description, w.alias].filter((v) => typeof v === "string").some((v) => v.toLowerCase().includes(q));
1489
2325
  });
1490
- }, [workflows, search, statusFilter, tagFilter, tagsByKey]);
2326
+ }, [
2327
+ workflows,
2328
+ search,
2329
+ statusFilter,
2330
+ tagFilter,
2331
+ tagsByKey,
2332
+ folderFilter,
2333
+ projectFilter
2334
+ ]);
2335
+ const toggleSelected = (id) => {
2336
+ setSelectedIds((prev) => {
2337
+ const next = new Set(prev);
2338
+ if (next.has(id)) next.delete(id);
2339
+ else next.add(id);
2340
+ return next;
2341
+ });
2342
+ };
2343
+ const clearSelection = () => {
2344
+ setSelectedIds(/* @__PURE__ */ new Set());
2345
+ setSelectMode(false);
2346
+ void refetch();
2347
+ };
1491
2348
  const assistantControls = useMemo(
1492
2349
  () => workflowsListControls({
1493
2350
  page: tr("fluidgrids.workflowsList.title", "Workflows"),
@@ -1575,7 +2432,14 @@ function WorkflowsList() {
1575
2432
  return (
1576
2433
  // min-h-screen (matching the sibling pages) makes short content still fill
1577
2434
  // the viewport, keeping the shell footer below the fold.
1578
- /* @__PURE__ */ jsxs("main", { className: "flex min-h-screen w-full flex-col bg-background-primary", children: [
2435
+ /* @__PURE__ */ jsxs("main", { className: "flex min-h-screen w-full flex-row bg-background-primary", children: [
2436
+ /* @__PURE__ */ jsx(
2437
+ WorkflowFolderSidebar,
2438
+ {
2439
+ selectedFolderId: folderFilter,
2440
+ onSelectFolder: setFolderFilter
2441
+ }
2442
+ ),
1579
2443
  /* @__PURE__ */ jsxs(
1580
2444
  "div",
1581
2445
  {
@@ -1636,6 +2500,28 @@ function WorkflowsList() {
1636
2500
  }
1637
2501
  )
1638
2502
  ] }),
2503
+ /* @__PURE__ */ jsx(
2504
+ WorkflowProjectSelect,
2505
+ {
2506
+ selectedProjectId: projectFilter,
2507
+ onSelectProject: setProjectFilter
2508
+ }
2509
+ ),
2510
+ /* @__PURE__ */ jsxs(
2511
+ Button,
2512
+ {
2513
+ variant: selectMode ? "secondary" : "outline",
2514
+ size: "sm",
2515
+ onClick: () => {
2516
+ setSelectMode((v) => !v);
2517
+ setSelectedIds(/* @__PURE__ */ new Set());
2518
+ },
2519
+ children: [
2520
+ /* @__PURE__ */ jsx(Icon, { icon: "mynaui:checkbox", className: "size-4" }),
2521
+ tr("fluidgrids.workflowsList.bulk.selectToggle", "Select")
2522
+ ]
2523
+ }
2524
+ ),
1639
2525
  presentStatuses.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
1640
2526
  /* @__PURE__ */ jsx(
1641
2527
  "button",
@@ -1691,6 +2577,13 @@ function WorkflowsList() {
1691
2577
  ]
1692
2578
  }
1693
2579
  ),
2580
+ selectedIds.size > 0 && /* @__PURE__ */ jsx(
2581
+ WorkflowBulkActionsBar,
2582
+ {
2583
+ selectedIds: [...selectedIds],
2584
+ onDone: clearSelection
2585
+ }
2586
+ ),
1694
2587
  loading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ jsx(SkeletonCard, {}, i)) }) : error ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex max-w-md flex-col items-center gap-3 rounded-xl border border-border bg-card p-8 text-center", children: [
1695
2588
  /* @__PURE__ */ jsx(
1696
2589
  Icon,
@@ -1752,40 +2645,53 @@ function WorkflowsList() {
1752
2645
  )
1753
2646
  }
1754
2647
  )
1755
- ] }) }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4", children: filtered.map((workflow) => /* @__PURE__ */ jsx(
1756
- CardWorkflow,
1757
- {
1758
- workflow: {
1759
- id: workflow.id,
1760
- workflow_key: workflow.workflowKey,
1761
- version: workflow.version,
1762
- name: workflow.name,
1763
- description: workflow.description ?? void 0,
1764
- status: workflow.status ?? void 0,
1765
- alias: workflow.alias ?? void 0,
1766
- updated_at: workflow.updatedAt ?? void 0,
1767
- created_at: workflow.createdAt ?? void 0,
1768
- total_versions: workflow.totalVersions ?? void 0,
1769
- tags: (tagsByKey[workflow.workflowKey] ?? []).map((a) => ({
1770
- id: a.tagId,
1771
- label: a.tagInfo?.label ?? a.tagInfo?.key ?? tr(
1772
- "fluidgrids.workflowsList.cardTagFallbackLabel",
1773
- "Tag"
1774
- ),
1775
- color: a.tagInfo?.color ?? void 0
1776
- }))
1777
- },
1778
- onUpdateSuccess: () => refetch(),
1779
- onExport: () => void handleExport(workflow.id),
1780
- onExportAs: codeFirst ? (format) => void handleExportAs(
1781
- workflow.workflowKey,
1782
- workflow.version,
1783
- format
1784
- ) : void 0,
1785
- exportingFormat: exportingKey === workflow.workflowKey ? exporting : null
1786
- },
1787
- workflow.id
1788
- )) })
2648
+ ] }) }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4", children: filtered.map((workflow) => /* @__PURE__ */ jsxs("div", { className: "relative", children: [
2649
+ selectMode && /* @__PURE__ */ jsx(
2650
+ Checkbox,
2651
+ {
2652
+ className: "absolute right-3 top-3 z-10 bg-background-primary",
2653
+ checked: selectedIds.has(workflow.id),
2654
+ onCheckedChange: () => toggleSelected(workflow.id),
2655
+ "aria-label": tr(
2656
+ "fluidgrids.workflowsList.bulk.selectWorkflowAriaLabel",
2657
+ "Select workflow"
2658
+ )
2659
+ }
2660
+ ),
2661
+ /* @__PURE__ */ jsx(
2662
+ CardWorkflow,
2663
+ {
2664
+ workflow: {
2665
+ id: workflow.id,
2666
+ workflow_key: workflow.workflowKey,
2667
+ version: workflow.version,
2668
+ name: workflow.name,
2669
+ description: workflow.description ?? void 0,
2670
+ status: workflow.status ?? void 0,
2671
+ alias: workflow.alias ?? void 0,
2672
+ updated_at: workflow.updatedAt ?? void 0,
2673
+ created_at: workflow.createdAt ?? void 0,
2674
+ total_versions: workflow.totalVersions ?? void 0,
2675
+ tags: (tagsByKey[workflow.workflowKey] ?? []).map((a) => ({
2676
+ id: a.tagId,
2677
+ label: a.tagInfo?.label ?? a.tagInfo?.key ?? tr(
2678
+ "fluidgrids.workflowsList.cardTagFallbackLabel",
2679
+ "Tag"
2680
+ ),
2681
+ color: a.tagInfo?.color ?? void 0
2682
+ }))
2683
+ },
2684
+ onUpdateSuccess: () => refetch(),
2685
+ onExport: () => void handleExport(workflow.id),
2686
+ onExportAs: codeFirst ? (format) => void handleExportAs(
2687
+ workflow.workflowKey,
2688
+ workflow.version,
2689
+ format
2690
+ ) : void 0,
2691
+ exportingFormat: exportingKey === workflow.workflowKey ? exporting : null
2692
+ }
2693
+ )
2694
+ ] }, workflow.id)) })
1789
2695
  ]
1790
2696
  }
1791
2697
  ),